--client-option, -t Send option to client (format: key=value), repeat to add more options
--check-origin, -O Do not allow websocket connection from different origin
--once, -o Accept only one client and exit on disconnection
- --ssl, -S Enable ssl
- --ssl-cert, -C Ssl certificate file path
- --ssl-key, -K Ssl key file path
- --ssl-ca, -A Ssl ca file path
+ --ssl, -S Enable SSL
+ --ssl-cert, -C SSL certificate file path
+ --ssl-key, -K SSL key file path
+ --ssl-ca, -A SSL CA file path for client certificate verification
--debug, -d Set log level (0-9, default: 7)
--version, -v Print the version and exit
--help, -h Print this text and exit
- You can even run a none shell command like vim, try: `ttyd vim`, the web broswer will show you a vim editor.
- Sharing single process with multiple clients: `ttyd tmux new -A -s ttyd vim`, run `tmux new -A -s ttyd` to connect to the tmux session from terminal.
+## SSL how-to
+
+Generate SSL CA and self signed server/client certificates:
+
+```bash
+# CA
+openssl genrsa -out ca.key 4096
+openssl req -new -x509 -days 365 -key ca.key -out ca.crt
+# server certificate
+openssl req -newkey rsa:2048 -nodes -keyout server.key -out server.csr
+openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
+# client certificate (the p12/pem format may be useful for some clients)
+openssl req -newkey rsa:2048 -nodes -keyout client.key -out client.csr
+openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt
+openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12
+openssl pkcs12 -in client.p12 -out client.pem -clcerts
+```
+
+Then start ttyd:
+
+```bash
+ttyd --ssl --ssl-cert ca.crt --ssl-key ca.key --ssl-ca ca.crt bash
+```
+
+If you don't want to enable client certificate verification, remove the `--ssl-ca` option.
+
## Docker and ttyd
Docker containers are jailed environments which are more secure, this is useful for protecting the host system, you may use ttyd with docker like this:
if (lws_write_http(wsi, index_html, index_html_len) < 0)
return 1;
goto try_to_reuse;
+ case LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION:
+ if (!len || (SSL_get_verify_result((SSL*)in) != X509_V_OK)) {
+ int err = X509_STORE_CTX_get_error((X509_STORE_CTX*)user);
+ int depth = X509_STORE_CTX_get_error_depth((X509_STORE_CTX*)user);
+ const char* msg = X509_verify_cert_error_string(err);
+ lwsl_err("client certificate verification error: %s (%d), depth: %d\n", msg, err, depth);
+ return 1;
+ }
+ break;
default:
break;
}
" --client-option, -t Send option to client (format: key=value), repeat to add more options\n"
" --check-origin, -O Do not allow websocket connection from different origin\n"
" --once, -o Accept only one client and exit on disconnection\n"
- " --ssl, -S Enable ssl\n"
- " --ssl-cert, -C Ssl certificate file path\n"
- " --ssl-key, -K Ssl key file path\n"
- " --ssl-ca, -A Ssl ca file path\n"
+ " --ssl, -S Enable SSL\n"
+ " --ssl-cert, -C SSL certificate file path\n"
+ " --ssl-key, -K SSL key file path\n"
+ " --ssl-ca, -A SSL CA file path for client certificate verification\n"
" --debug, -d Set log level (0-9, default: 7)\n"
" --version, -v Print the version and exit\n"
" --help, -h Print this text and exit\n",
"!DHE-RSA-AES256-SHA256:"
"!AES256-GCM-SHA384:"
"!AES256-SHA256";
+ if (strlen(info.ssl_ca_filepath) > 0)
+ info.options |= LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT;
#if LWS_LIBRARY_VERSION_MAJOR == 2
info.options |= LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS;
#endif