From a97c4ee91f0bc6f02ce071830804c9bfa112c38d Mon Sep 17 00:00:00 2001 From: Janos Kasza Date: Tue, 21 Jan 2020 17:55:18 +0100 Subject: [PATCH] Force ssh connection (#226) * Setting lower websocket ping interval values * Updated package version * Ask ssh user from the standard input and force ssh connection * Removed --sshaskuser option as it's not necessary * Bumping the version to 1.3.0 --- README.md | 11 ++++++++--- docs/API.md | 1 + index.js | 6 ++++++ package.json | 2 +- src/server/cli/index.ts | 4 ++-- src/server/cli/options.ts | 1 + src/server/cli/parseArgs.ts | 3 ++- src/server/command/index.ts | 7 ++++--- src/server/command/ssh.ts | 5 +++++ src/server/wetty/index.ts | 3 ++- 10 files changed, 32 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index e8d47e4..43d2fb3 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,11 @@ # 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 +35,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] [--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,7 +43,8 @@ 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 diff --git a/docs/API.md b/docs/API.md index 89bc3b1..3f6e953 100644 --- a/docs/API.md +++ b/docs/API.md @@ -33,6 +33,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..d173a4c 100755 --- a/index.js +++ b/index.js @@ -67,6 +67,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/package.json b/package.json index 9238d81..263c3cb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wetty", - "version": "1.2.4", + "version": "1.3.0", "description": "WeTTY = Web + TTY. Terminal access in browser over http/https", "homepage": "https://github.com/butlerx/wetty", "repository": { 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..01d4f9c 100644 --- a/src/server/cli/options.ts +++ b/src/server/cli/options.ts @@ -12,6 +12,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..792ee14 100644 --- a/src/server/cli/parseArgs.ts +++ b/src/server/cli/parseArgs.ts @@ -4,7 +4,7 @@ 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, @@ -22,6 +22,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..91415d3 100644 --- a/src/server/command/index.ts +++ b/src/server/command/index.ts @@ -25,9 +25,10 @@ export default ( }, }: Socket, { user, host, port, auth, pass, key }: SSH, - command: string + command: string, + forcessh: boolean ): { args: string[]; user: boolean } => ({ - args: localhost(host) + args: !forcessh && localhost(host) ? loginOptions(command, remoteAddress) : sshOptions( urlArgs(referer, { @@ -40,7 +41,7 @@ export default ( key ), user: - localhost(host) || + (!forcessh && localhost(host)) || user !== '' || user.includes('@') || address(referer, user, host).includes('@'), diff --git a/src/server/command/ssh.ts b/src/server/command/ssh.ts index 6f43a90..ece47e2 100644 --- a/src/server/command/ssh.ts +++ b/src/server/command/ssh.ts @@ -15,6 +15,10 @@ export default function sshOptions( port, '-o', `PreferredAuthentications=${auth}`, + '-o', + 'UserKnownHostsFile=/dev/null', + '-o', + 'StrictHostKeyChecking=no', ]; logger.info(`Authentication Type: ${auth}`); if (!isUndefined(key)) { @@ -26,6 +30,7 @@ export default function sshOptions( if (auth === 'none') { sshRemoteOptsBase.splice(sshRemoteOptsBase.indexOf('-o'), 2); } + if (cmd === '') { return sshRemoteOptsBase; } diff --git a/src/server/wetty/index.ts b/src/server/wetty/index.ts index cbb1d0c..3e44ab9 100644 --- a/src/server/wetty/index.ts +++ b/src/server/wetty/index.ts @@ -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(' '),