From af9a7c5812f3bbdcb7fe03658533c9cf704e97af Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Fri, 1 Jun 2018 02:45:38 -0600 Subject: [PATCH] put ssh detection on full auto --- examples/telebit.yml.tpl | 1 + lib/sorting-hat.js | 55 +++++++++++++++++++++++++++------------- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/examples/telebit.yml.tpl b/examples/telebit.yml.tpl index 2bde9d3..da37f50 100644 --- a/examples/telebit.yml.tpl +++ b/examples/telebit.yml.tpl @@ -1,6 +1,7 @@ agree_tos: true # agree to the Telebit, Greenlock, and Let's Encrypt TOSes community_member: true # receive infrequent relevant updates telemetry: true # contribute to project telemetric data +ssh_auto: 22 # forward ssh-looking packets, from any connection, to port 22 remote_options: https_redirect: true # redirect http to https remotely (default) local_ports: # ports to forward diff --git a/lib/sorting-hat.js b/lib/sorting-hat.js index b200084..b7fd3ff 100644 --- a/lib/sorting-hat.js +++ b/lib/sorting-hat.js @@ -56,6 +56,16 @@ module.exports.assign = function (state, tun, cb) { console.log('first message from', tun); var net = state.net || require('net'); + function trySsh(tun, cb) { + // https://security.stackexchange.com/questions/43231/plausibly-deniable-ssh-does-it-make-sense?rq=1 + // https://tools.ietf.org/html/rfc4253#section-4.2 + if (false === state.config.ssh_auto || 'SSH-2.0-' !== tun.data.slice(0, 8).toString()) { + cb(null, false); + return; + } + cb(null, getNetConn(state.config.sshPort || 22)); + } + var handlers = {}; handlers.http = function (socket) { if (!state.greenlock) { @@ -201,11 +211,30 @@ module.exports.assign = function (state, tun, cb) { //console.log('[hit tls server]', tlsSocket.remoteFamily, tlsSocket.remoteAddress, tlsSocket.remotePort, tlsSocket.localPort); //console.log(addr); var conf = state.config.servernames[tlsSocket.servername]; - if (!conf || !conf.handler) { - handlers.https(tlsSocket); - return; - } - invokeHandler(conf, tlsSocket, tun, id); + tlsSocket.once('data', function (firstChunk) { + tlsSocket.pause(); + //tlsSocket.unshift(firstChunk); + tlsSocket._handle.onread(firstChunk.length, firstChunk); + + trySsh({ data: firstChunk }, function (err, conn) { + process.nextTick(function () { tlsSocket.resume(); }); + + if (conn) { + conn.pipe(tlsSocket); + tlsSocket.pipe(conn); + return; + } + + if (!conf || !conf.handler) { + console.log('https default handler'); + handlers.https(tlsSocket); + return; + } + + console.log('https invokeHandler'); + invokeHandler(conf, tlsSocket, tun, id); + }); + }); }); } @@ -284,19 +313,11 @@ module.exports.assign = function (state, tun, cb) { return; } - function trySsh(tun) { - // https://security.stackexchange.com/questions/43231/plausibly-deniable-ssh-does-it-make-sense?rq=1 - // https://tools.ietf.org/html/rfc4253#section-4.2 - if ('SSH-2.0-' !== tun.data.slice(0, 8).toString()) { - return false; - } - cb(null, getNetConn(state.config.sshPort || 22)); - return true; - } - if ('tcp' === tun.service) { - if (trySsh(tun)) { return; } - cb(new Error("No TCP handler")); + trySsh(tun, function (err, conn) { + if (conn) { cb(null, conn); return; } + cb(new Error("No TCP handler")); + }); } console.warn("Unknown service '" + tun.service + "'");