Browse Source

Autologin Feature Added (#122)

Login by passing username and password in url as query parameters. 
Migrated to node-pty which is currently maintained and updated. 
added feature to put in global username and password
Added server keep alive in ssh options to keep the session alive.
pull/143/head
Koushik M.L.N 6 years ago
committed by Cian Butler
parent
commit
c14ee99081
  1. 1
      .gitignore
  2. 8
      Dockerfile
  3. 3
      Dockerfile-ssh
  4. 26
      README.md
  5. 7
      cli.mjs
  6. 15
      docker-compose.yml
  7. 1
      public/wetty/index.html
  8. 4
      src/hterm_all.js
  9. 22
      wetty.mjs

1
.gitignore

@ -13,5 +13,6 @@ logs
results
npm-debug.log
.idea
node_modules/*
.esm-cache

8
Dockerfile

@ -3,13 +3,15 @@ WORKDIR /usr/src/app
RUN apk add --update build-base python
COPY . /usr/src/app
RUN yarn
FROM node:8-alpine
MAINTAINER butlerx@notthe.cloud
WORKDIR /app
RUN adduser -D -h /home/term -s /bin/sh term && \
( echo "term:term" | chpasswd ) && \
apk add openssh-client
apk add openssh-client && \
apk add sshpass
USER term
EXPOSE 3000
COPY --from=builder /usr/src/app /app
CMD node bin
RUN mkdir ~/.ssh
CMD ssh-keyscan -H wetty-ssh >> ~/.ssh/known_hosts && node bin

3
Dockerfile-ssh

@ -0,0 +1,3 @@
FROM sickp/alpine-sshd:latest
RUN adduser -D -h /home/term -s /bin/sh term && \
( echo "term:term" | chpasswd )

26
README.md

@ -22,6 +22,12 @@ wetty -p 3000
If you run it as root it will launch `/bin/login` (where you can specify the
user name), else it will launch `ssh` and connect by default to `localhost`.
* `apt-get install sshpass` (debian eg. Ubuntu) for auto-login feature
* `yum install sshpass` (red hat flavours eg. CentOs) for auto-login feature
Run on HTTP:
-----------
If instead you wish to connect to a remote host you can specify the `--sshhost`
option, the SSH port using the `--sshport` option and the SSH user using the
@ -35,8 +41,26 @@ or
`http://yourserver:3000/ssh/<username>`
You can pass an optional password as query parameter to use auto-login feature.
`http://yourserver:3000/wetty/ssh/<username>?sshpass=<password>`
or
`http://yourserver:3000/ssh/<username>?sshpass=<password>`
## Run on HTTPS
You can also pass the SSH user name and password as query parameters and auto-login the user like this (Only while running as a non root account):
`http://yourserver:3000/wetty/autologin?sshuser=<username>&sshpass=<password>`
This is just an additional feature and the security implications for passing the password in the url will have to be taken care separately.
Run on HTTPS:
------------
Always use HTTPS. If you don't have SSL certificates from a CA you can create a
self signed certificate using this command:
@ -88,6 +112,8 @@ use:
http://yourserver.com/wetty
```
**Note that if your Nginx is configured for HTTPS you should run wetty without SSL.**
Else if you are running `bin/index.js` as a regular user you can use:
```

7
cli.mjs

@ -25,6 +25,10 @@ const opts = optimist
demand : false,
description: 'ssh user',
},
sshpass: {
demand : false,
description: 'ssh password',
},
sshauth: {
demand : false,
description: 'defaults to "password", you can use "publickey,password" instead',
@ -52,6 +56,7 @@ if (opts.help) {
}
const sshuser = opts.sshuser || process.env.SSHUSER || '';
const sshpass = opts.sshpass || process.env.SSHPASS || '';
const sshhost = opts.sshhost || process.env.SSHHOST || 'localhost';
const sshauth = opts.sshauth || process.env.SSHAUTH || 'password,keyboard-interactive';
const sshport = opts.sshport || process.env.SSHPORT || 22;
@ -81,7 +86,7 @@ process.on('uncaughtException', err => {
console.error(`Error: ${err}`);
});
const tty = wetty(port, sshuser, sshhost, sshport, sshauth, sshkey, opts.ssl);
const tty = wetty(port, sshuser, sshpass, sshhost, sshport, sshauth, sshkey, opts.ssl);
tty.on('exit', code => {
console.log(`exit with code: ${code}`);
});

15
docker-compose.yml

@ -1,4 +1,4 @@
version: "3"
version: "3.5"
services:
wetty:
@ -11,5 +11,16 @@ services:
- "3000:3000"
environment:
PORT: 3000
SSHHOST: 'localhost'
SSHHOST: 'wetty-ssh'
SSHPORT: 22
wetty-ssh:
build:
context: .
dockerfile: Dockerfile-ssh
container_name: 'wetty-ssh'
networks:
default:
name: wetty

1
public/wetty/index.html

@ -3,7 +3,6 @@
<head>
<meta charset="UTF-8">
<title>Wetty - The WebTTY Terminal Emulator</title>
<script src="/wetty/socket.io/socket.io.js"></script>
<style>
html, body {
height: 100%;

4
src/hterm_all.js

@ -18387,6 +18387,4 @@ lib.resource.add('hterm/changelog/date', 'text/plain',
lib.resource.add('hterm/git/HEAD', 'text/plain',
'git rev-parse HEAD' +
''
);
);

22
wetty.mjs

@ -6,6 +6,7 @@ import server from 'socket.io';
import { spawn } from 'node-pty';
import EventEmitter from 'events';
import favicon from 'serve-favicon';
import url from 'url';
const app = express();
app.use(favicon(`${__dirname}/public/favicon.ico`));
@ -36,12 +37,14 @@ function createServer(port, sslopts) {
});
}
function getCommand(socket, sshuser, sshhost, sshport, sshauth, sshkey) {
function getCommand(socket, sshuser, sshpass, sshhost, sshport, sshauth, sshkey) {
const { request } = socket;
const match = request.headers.referer.match('.+/ssh/.+$');
const sshAddress = sshuser ? `${sshuser}@${sshhost}` : sshhost;
const sshPath = sshuser || match ? 'ssh' : path.join(__dirname, 'bin/ssh');
const ssh = match ? `${match[0].split('/ssh/').pop()}@${sshhost}` : sshAddress;
const referer = url.parse(request.headers.referer, true);
sshpass = referer.query.sshpass ? referer.query.sshpass : sshpass;
let sshPath = sshuser || match ? 'ssh' : path.join(__dirname, 'bin/ssh');
const ssh = match ? `${match[0].split('/ssh/').pop().split('?')[0]}@${sshhost}` : sshAddress;
const sshRemoteOptsBase = [
sshPath,
ssh,
@ -50,9 +53,14 @@ function getCommand(socket, sshuser, sshhost, sshport, sshauth, sshkey) {
'-o',
`PreferredAuthentications=${sshauth}`,
]
const sshRemoteOpts = sshkey ? sshRemoteOptsBase.concat(['-i', sshkey])
: sshRemoteOptsBase
let sshRemoteOpts;
if (sshkey)
sshRemoteOpts = sshRemoteOptsBase.concat(['-i', sshkey]);
else if (sshpass)
sshRemoteOpts = ['sshpass', '-p', sshpass].concat(sshRemoteOptsBase);
else
sshRemoteOpts = sshRemoteOptsBase;
return [
process.getuid() === 0 && sshhost === 'localhost'
? ['login', '-h', socket.client.conn.remoteAddress.split(':')[3]]
@ -62,12 +70,12 @@ function getCommand(socket, sshuser, sshhost, sshport, sshauth, sshkey) {
];
}
export default function start(port, sshuser, sshhost, sshport, sshauth, sshkey, sslopts) {
export default function start(port, sshuser, sshpass, sshhost, sshport, sshauth, sshkey, sslopts) {
const events = new EventEmitter();
const io = server(createServer(port, sslopts), { path: '/wetty/socket.io' });
io.on('connection', socket => {
console.log(`${new Date()} Connection accepted.`);
const [args, ssh] = getCommand(socket, sshuser, sshhost, sshport, sshauth, sshkey);
const [args, ssh] = getCommand(socket, sshuser, sshpass, sshhost, sshport, sshauth, sshkey);
const term = spawn('/usr/bin/env', args, {
name: 'xterm-256color',
cols: 80,

Loading…
Cancel
Save