diff --git a/README.md b/README.md index e8d47e4..9aa2770 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # WeTTY = Web + TTY. -![All Contributors](https://img.shields.io/badge/all_contributors-33-orange.svg?style=flat-square) + +![All Contributors](https://img.shields.io/badge/all_contributors-33-orange.svg?style=flat-square) + ![Version](https://img.shields.io/badge/version-1.1.7-blue.svg?cacheSeconds=2592000) ![Node Version](https://img.shields.io/badge/node-%3E%3D6.9-blue.svg) [![Documentation](https://img.shields.io/badge/documentation-yes-brightgreen.svg)](https://github.com/butlerx/wetty/tree/master/docs) @@ -31,7 +33,7 @@ yarn global add wetty ## Usage ```sh -wetty [-h] [--port PORT] [--base BASE] [--sshhost SSH_HOST] [--sshport SSH_PORT] [--sshuser SSH_USER] [--host HOST] [--command COMMAND] [--bypasshelmet] [--title TITLE] [--sslkey SSL_KEY_PATH] [--sslcert SSL_CERT_PATH] +wetty [-h] [--port PORT] [--base BASE] [--sshhost SSH_HOST] [--sshport SSH_PORT] [--sshuser SSH_USER] [--sshaskuser] [--host HOST] [--command COMMAND] [--forcessh] [--bypasshelmet] [--title TITLE] [--sslkey SSL_KEY_PATH] [--sslcert SSL_CERT_PATH] ``` Open your browser on `http://yourserver:3000/wetty` and you will prompted to @@ -39,11 +41,14 @@ login. Or go to `http://yourserver:3000/wetty/ssh/` to specify the user before hand. 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`. +user name), else it will launch `ssh` and connect by default to `localhost`. The +SSH connection can be forced using the `--forcessh` option. 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 -`--sshuser` option. +`--sshuser` option. Alternatively you can ask the user from the stard input of +the terminal later (and ignoring `--sshuser`) if using the `--sshaskuser` +option. Check out the [Flags docs](https://github.com/butlerx/wetty/blob/master/docs/flags.md) for a diff --git a/bin/ssh-with-user b/bin/ssh-with-user new file mode 100755 index 0000000..5df1e64 --- /dev/null +++ b/bin/ssh-with-user @@ -0,0 +1,9 @@ +#!/bin/bash + +set -e + +while [ -z "${username}" ]; do + echo -n "localhost login: " + read username +done +ssh -l "${username}" $@ diff --git a/docs/API.md b/docs/API.md index 89bc3b1..c06bdb4 100644 --- a/docs/API.md +++ b/docs/API.md @@ -21,6 +21,7 @@ Starts WeTTy Server | :------------------------ | --------- | ------------- | ---------------------------------------------------------------------------------------------------------------------- | | [ssh] | `Object` | | SSH settings | | [ssh.user] | `string` | `"''"` | default user for ssh | +| [ssh.askuser] | `boolean` | `false` | ask ssh user from the standard input | | [ssh.host] | `string` | `"localhost"` | machine to ssh too | | [ssh.auth] | `string` | `"password"` | authtype to use | | [ssh.port] | `number` | `22` | port to connect to over ssh | @@ -33,6 +34,7 @@ Starts WeTTy Server | [serverConf.title] | `string` | `'WeTTy'` | Title of the server | | [serverConf.bypasshelmet] | `boolean` | `false` | if helmet should be disabled on the sever | | [command] | `string` | `"''"` | The command to execute. If running as root and no host specified this will be login if a host is specified will be ssh | +| [forcessh] | `boolean` | `false` | Connecting through ssh even if running as root | | [ssl] | `Object` | | SSL settings | | [ssl.key] | `string` | | Path to ssl key | | [ssl.cert] | `string` | | Path to ssl cert | diff --git a/index.js b/index.js index 7e2fb59..243dba7 100755 --- a/index.js +++ b/index.js @@ -41,6 +41,12 @@ if (require.main === module) { type: 'string', default: process.env.SSHUSER || '', }, + sshaskuser: { + demand: false, + description: 'ask ssh user from the standard input', + type: 'boolean', + default: process.env.SSHASKUSER || false + }, title: { demand: false, description: 'window title', @@ -67,6 +73,12 @@ if (require.main === module) { type: 'string', default: process.env.SSHKEY || undefined, }, + forcessh: { + demand: false, + description: 'Connecting through ssh even if running as root', + type: 'boolean', + default: process.env.FORCESSH || false + }, base: { demand: false, alias: 'b', diff --git a/src/server/cli/index.ts b/src/server/cli/index.ts index 97316ef..5941383 100644 --- a/src/server/cli/index.ts +++ b/src/server/cli/index.ts @@ -6,8 +6,8 @@ import { unWrapArgs } from './parseArgs'; export default function init(opts: CLI): void { if (!opts.help) { - const { ssh, server, command, ssl } = unWrapArgs(opts); - WeTTy(ssh, server, command, ssl).catch(err => { + const { ssh, server, command, forcessh, ssl } = unWrapArgs(opts); + WeTTy(ssh, server, command, forcessh, ssl).catch(err => { logger.error(err); process.exitCode = 1; }); diff --git a/src/server/cli/options.ts b/src/server/cli/options.ts index aab6871..37d63be 100644 --- a/src/server/cli/options.ts +++ b/src/server/cli/options.ts @@ -2,6 +2,7 @@ export interface Options { sshhost: string; sshport: number; sshuser: string; + sshaskuser: boolean; sshauth: string; sshkey?: string; sshpass?: string; @@ -12,6 +13,7 @@ export interface Options { port: number; title: string; command?: string; + forcessh?: boolean; bypasshelmet?: boolean; } diff --git a/src/server/cli/parseArgs.ts b/src/server/cli/parseArgs.ts index 7daf499..24cf68b 100644 --- a/src/server/cli/parseArgs.ts +++ b/src/server/cli/parseArgs.ts @@ -4,10 +4,11 @@ import { Options } from './options'; export function unWrapArgs( args: Options -): { ssh: SSH; server: Server; command?: string; ssl?: SSL } { +): { ssh: SSH; server: Server; command?: string; forcessh?: boolean; ssl?: SSL } { return { ssh: { user: args.sshuser, + askuser: args.sshaskuser, host: args.sshhost, auth: args.sshauth, port: args.sshport, @@ -22,6 +23,7 @@ export function unWrapArgs( bypasshelmet: args.bypasshelmet || false, }, command: args.command, + forcessh: args.forcessh, ssl: isUndefined(args.sslkey) || isUndefined(args.sslcert) ? undefined diff --git a/src/server/command/index.ts b/src/server/command/index.ts index 4af1b27..08ec649 100644 --- a/src/server/command/index.ts +++ b/src/server/command/index.ts @@ -24,14 +24,16 @@ export default ( conn: { remoteAddress }, }, }: Socket, - { user, host, port, auth, pass, key }: SSH, - command: string + { user, askuser, host, port, auth, pass, key }: SSH, + command: string, + forcessh: boolean ): { args: string[]; user: boolean } => ({ - args: localhost(host) + args: !forcessh && localhost(host) ? loginOptions(command, remoteAddress) : sshOptions( urlArgs(referer, { - host: address(referer, user, host), + sshcommand: askuser ? './bin/ssh-with-user' : 'ssh', + host: askuser ? host : address(referer, user, host), port: `${port}`, pass: pass || '', command, diff --git a/src/server/command/ssh.ts b/src/server/command/ssh.ts index 6f43a90..5d05465 100644 --- a/src/server/command/ssh.ts +++ b/src/server/command/ssh.ts @@ -3,18 +3,23 @@ import parseCommand from './parse'; import logger from '../utils/logger'; export default function sshOptions( - { pass, path, command, host, port, auth }: { [s: string]: string }, + { sshcommand, pass, path, command, host, port, auth }: { [s: string]: string }, key?: string ): string[] { const cmd = parseCommand(command, path); + logger.info(`ssh command: ${sshcommand}`); const sshRemoteOptsBase = [ - 'ssh', + sshcommand, host, '-t', '-p', port, '-o', `PreferredAuthentications=${auth}`, + '-o', + 'UserKnownHostsFile=/dev/null', + '-o', + 'StrictHostKeyChecking=no', ]; logger.info(`Authentication Type: ${auth}`); if (!isUndefined(key)) { diff --git a/src/server/interfaces.ts b/src/server/interfaces.ts index 16eb4b1..3b52d18 100644 --- a/src/server/interfaces.ts +++ b/src/server/interfaces.ts @@ -1,5 +1,6 @@ export interface SSH { user: string; + askuser: boolean; host: string; auth: string; port: number; diff --git a/src/server/wetty/index.ts b/src/server/wetty/index.ts index cbb1d0c..a9a44fa 100644 --- a/src/server/wetty/index.ts +++ b/src/server/wetty/index.ts @@ -13,7 +13,7 @@ import { SSH, SSL, SSLBuffer, Server } from '../interfaces'; * @name startWeTTy */ export default function startWeTTy( - ssh: SSH = { user: '', host: 'localhost', auth: 'password', port: 22 }, + ssh: SSH = { user: '', askuser: false, host: 'localhost', auth: 'password', port: 22 }, serverConf: Server = { base: '/wetty/', port: 3000, @@ -22,6 +22,7 @@ export default function startWeTTy( bypasshelmet: false, }, command = '', + forcessh = false, ssl?: SSL ): Promise { return loadSSL(ssl).then((sslBuffer: SSLBuffer) => { @@ -44,7 +45,7 @@ export default function startWeTTy( * @name connection */ logger.info('Connection accepted.'); - const { args, user: sshUser } = getCommand(socket, ssh, command); + const { args, user: sshUser } = getCommand(socket, ssh, command, forcessh); logger.debug('Command Generated', { user: sshUser, cmd: args.join(' '),