From 2de2fd3c6101afb298c60d2f7c2841cdc356200f Mon Sep 17 00:00:00 2001 From: Janos Kasza Date: Tue, 27 Oct 2020 14:13:19 +0100 Subject: [PATCH] Added --ssh-config option for alternate ssh configuration --- README.md | 45 +++++++++++++++++++++------------------ conf/config.json5 | 27 ++++++++++++----------- docs/API.md | 1 + docs/atoz.md | 45 ++++++++++++++++++++++++--------------- src/main.ts | 4 ++++ src/server/command.ts | 3 ++- src/server/command/ssh.ts | 4 +++- src/shared/config.ts | 1 + src/shared/defaults.ts | 1 + src/shared/interfaces.ts | 1 + 10 files changed, 79 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index 1c8e0c5..cd39cff 100644 --- a/README.md +++ b/README.md @@ -39,27 +39,30 @@ yarn global add wetty ```sh $ wetty --help Options: - --help, -h Print help message [boolean] - --version Show version number [boolean] - --conf config file to load config from [string] - --ssl-key path to SSL key [string] - --ssl-cert path to SSL certificate [string] - --ssh-host ssh server host [string] - --ssh-port ssh server port [number] - --ssh-user ssh user [string] - --title window title [string] - --ssh-auth defaults to "password", you can use "publickey,password" - instead [string] - --ssh-pass ssh password [string] - --ssh-key path to an optional client private key (connection will be - password-less and insecure!) [string] - --force-ssh Connecting through ssh even if running as root [boolean] - --known-hosts path to known hosts file [string] - --base, -b base path to wetty [string] - --port, -p wetty listen port [number] - --host wetty listen host [string] - --command, -c command to run in shell [string] - --bypass-helmet disable helmet from placing security restrictions [boolean] + --help, -h Print help message [boolean] + --version Show version number [boolean] + --conf config file to load config from [string] + --ssl-key path to SSL key [string] + --ssl-cert path to SSL certificate [string] + --ssh-host ssh server host [string] + --ssh-port ssh server port [number] + --ssh-user ssh user [string] + --title window title [string] + --ssh-auth defaults to "password", you can use "publickey,password" + instead [string] + --ssh-pass ssh password [string] + --ssh-key path to an optional client private key (connection will be + password-less and insecure!) [string] + --ssh-config Specifies an alternative ssh configuration file. For further + details see "-F" option in ssh(1) [string] + --force-ssh Connecting through ssh even if running as root [boolean] + --known-hosts path to known hosts file [string] + --base, -b base path to wetty [string] + --port, -p wetty listen port [number] + --host wetty listen host [string] + --command, -c command to run in shell [string] + --allow-iframe Allow wetty to be embedded in an iframe, defaults to allowing + same origin [boolean] ``` Open your browser on `http://yourserver:3000/wetty` and you will prompted to diff --git a/conf/config.json5 b/conf/config.json5 index 15ddf3f..b955580 100644 --- a/conf/config.json5 +++ b/conf/config.json5 @@ -1,22 +1,23 @@ { ssh: { - // user: 'username', // default user to use when ssh-ing - host: 'localhost', // Server to ssh to - auth: 'password', // shh authentication, method. Defaults to "password", you can use "publickey,password" instead' - // pass: "password", // Password to use when sshing - // key: "", // path to an optional client private key, connection will be password-less and insecure! - port: 22, // Port to ssh to - knownHosts: '/dev/null', // ssh knownHosts file to use + // user: 'username', // default user to use when ssh-ing + host: 'localhost', // Server to ssh to + auth: 'password', // shh authentication, method. Defaults to "password", you can use "publickey,password" instead' + // pass: "password", // Password to use when sshing + // key: "", // path to an optional client private key, connection will be password-less and insecure! + port: 22, // Port to ssh to + knownHosts: '/dev/null', // ssh knownHosts file to use + // config: '/home/user/.wetty_ssh_config', // alternative ssh configuration file, see "-F" option in ssh(1) }, server: { - base: '/wetty/', // URL base to serve resources from - port: 3000, // Port to listen on - host: '0.0.0.0', // address to listen on - title: 'WeTTy - The Web Terminal Emulator', // Page title - bypassHelmet: false, // Disable Helmet security checks + base: '/wetty/', // URL base to serve resources from + port: 3000, // Port to listen on + host: '0.0.0.0', // address to listen on + title: 'WeTTy - The Web Terminal Emulator', // Page title + bypassHelmet: false, // Disable Helmet security checks }, - forceSSH: false, // Force sshing to local machine over login if running as root + forceSSH: false, // Force sshing to local machine over login if running as root command: 'login', // Command to run on server. Login will use ssh if connecting to different server /* ssl:{ diff --git a/docs/API.md b/docs/API.md index 3f6e953..f305464 100644 --- a/docs/API.md +++ b/docs/API.md @@ -26,6 +26,7 @@ Starts WeTTy Server | [ssh.port] | `number` | `22` | port to connect to over ssh | | [ssh.pass] | `string` | | Optional param of a password to use for ssh | | [ssh.key] | `string` | | path to an optional client private key (connection will be password-less and insecure!) | +| [ssh.config] | `string` | | Specifies an alternative ssh configuration file. For further details see "-F" option in ssh(1) | | [serverConf] | `Object` | | Server settings | | [serverConf.base] | `Object` | `'/wetty/'` | Server settings | | [serverConf.port] | `number` | `3000` | Port to run server on | diff --git a/docs/atoz.md b/docs/atoz.md index ffe5306..01c6612 100644 --- a/docs/atoz.md +++ b/docs/atoz.md @@ -347,6 +347,12 @@ username. have to use the key file and you can instead require a password but setting this to `--ssh-auth password`. You can specify both `--ssh-auth publickey,password` +`--ssh-config configfile` - alternative ssh configuration file. From ssh(1): + +> If a configuration file is given on the command line, the system-wide +> configuration file (/etc/ssh/ssh_config) will be ignored. The default for the +> per-user configuration file is ~/.ssh/config. + #### SSL settings explained These settings are specific to `openssl` to make `wetty` load https webserver so @@ -505,21 +511,26 @@ echo https://$(curl -s4 icanhazip.com)/wetty `wetty -h` configuration options for reference. ```bash - --help, -h Print help message [boolean] - --version Show version number [boolean] - --sslkey path to SSL key [string] - --sslcert path to SSL certificate [string] - --sshhost ssh server host [string] [default: "localhost"] - --sshport ssh server port [number] [default: 22] - --sshuser ssh user [string] [default: ""] - --title window title [string] [default: "WeTTy - The Web Terminal Emulator"] - --sshauth defaults to "password", you can use "publickey,password" instead[string] [default: "password"] - --sshpass ssh password [string] - --sshkey path to an optional client private key (connection will be password-less and insecure!) [string] - --forcessh Connecting through ssh even if running as root [boolean] [default: false] - --base, -b base path to wetty [string] [default: "/wetty/"] - --port, -p wetty listen port [number] [default: 3000] - --host wetty listen host [string] [default: "0.0.0.0"] - --command, -c command to run in shell [string] [default: "login"] - --bypasshelmet disable helmet from placing security restrictions [boolean] [default: false] + --help, -h Print help message [boolean] + --version Show version number [boolean] + --conf config file to load config from [string] + --ssl-key path to SSL key [string] + --ssl-cert path to SSL certificate [string] + --ssh-host ssh server host [string] [default: "localhost"] + --ssh-port ssh server port [number] [default: 22] + --ssh-user ssh user [string] [default: ""] + --title window title [string] [default: "WeTTy - The Web Terminal Emulator"] + --ssh-auth defaults to "password", you can use "publickey,password" instead [string] [default: "password"] + --ssh-pass ssh password [string] + --ssh-key path to an optional client private key (connection will be + password-less and insecure!) [string] + --ssh-config Specifies an alternative ssh configuration file. For further + details see "-F" option in ssh(1) [string] [default: ""] + --force-ssh Connecting through ssh even if running as root [boolean] [default: false] + --known-hosts path to known hosts file [string] + --base, -b base path to wetty [string] [default: "/wetty/"] + --port, -p wetty listen port [number] [default: 3000] + --host wetty listen host [string] [default: "0.0.0.0"] + --command, -c command to run in shell [string] [default: "login"] + --allow-iframe Allow wetty to be embedded in an iframe, defaults to allowing same origin [boolean] [default: false] ``` diff --git a/src/main.ts b/src/main.ts index 2ea3ef3..4b18f95 100644 --- a/src/main.ts +++ b/src/main.ts @@ -55,6 +55,10 @@ const opts = yargs 'path to an optional client private key (connection will be password-less and insecure!)', type: 'string', }) + .option('ssh-config', { + description: 'Specifies an alternative ssh configuration file. For further details see "-F" option in ssh(1)', + type: 'string', + }) .option('force-ssh', { description: 'Connecting through ssh even if running as root', type: 'boolean', diff --git a/src/server/command.ts b/src/server/command.ts index 3b51b1e..f60cc24 100644 --- a/src/server/command.ts +++ b/src/server/command.ts @@ -24,7 +24,7 @@ export const getCommand = ( conn: { remoteAddress }, }, }: Socket, - { user, host, port, auth, pass, key, knownHosts }: SSH, + { user, host, port, auth, pass, key, knownHosts, config }: SSH, command: string, forcessh: boolean, ): { args: string[]; user: boolean } => ({ @@ -39,6 +39,7 @@ export const getCommand = ( command, auth, knownHosts, + config: config || '', }), host: address(referer, user, host), }, diff --git a/src/server/command/ssh.ts b/src/server/command/ssh.ts index 1652643..09c70d7 100644 --- a/src/server/command/ssh.ts +++ b/src/server/command/ssh.ts @@ -2,7 +2,7 @@ import isUndefined from 'lodash/isUndefined.js'; import { logger } from '../../shared/logger.js'; export function sshOptions( - { pass, path, command, host, port, auth, knownHosts }: Record, + { pass, path, command, host, port, auth, knownHosts, config }: Record, key?: string, ): string[] { const cmd = parseCommand(command, path); @@ -11,6 +11,8 @@ export function sshOptions( 'ssh', host, '-t', + config !== '' ? '-F' : '', + config, '-p', port, '-o', diff --git a/src/shared/config.ts b/src/shared/config.ts index e0744c9..e01d68d 100644 --- a/src/shared/config.ts +++ b/src/shared/config.ts @@ -115,6 +115,7 @@ export function mergeCliConf(opts: Arguments, config: Config): Config { port: opts['ssh-port'], pass: opts['ssh-pass'], key: opts['ssh-key'], + config: opts['ssh-config'], knownHosts: opts['known-hosts'], }) as SSH, server: objectAssign(config.server, { diff --git a/src/shared/defaults.ts b/src/shared/defaults.ts index e4be0f2..46aca04 100644 --- a/src/shared/defaults.ts +++ b/src/shared/defaults.ts @@ -8,6 +8,7 @@ export const sshDefault: SSH = { key: process.env.SSHKEY || undefined, port: parseInt(process.env.SSHPORT || '22', 10), knownHosts: process.env.KNOWNHOSTS || '/dev/null', + config: process.env.SSHCONFIG || undefined, }; export const serverDefault: Server = { diff --git a/src/shared/interfaces.ts b/src/shared/interfaces.ts index faaacd3..b9bd722 100644 --- a/src/shared/interfaces.ts +++ b/src/shared/interfaces.ts @@ -7,6 +7,7 @@ export interface SSH { knownHosts: string; pass?: string; key?: string; + config?: string; } export interface SSL {