keep address, localPort (service), and encrypted

This commit is contained in:
AJ ONeal 2018-05-31 05:24:58 -06:00
parent acaf22c200
commit 5207012830
1 changed files with 90 additions and 78 deletions

View File

@ -78,6 +78,7 @@ module.exports.assign = function (state, tun, cb) {
state.httpRedirectServer.emit('connection', socket); state.httpRedirectServer.emit('connection', socket);
}; };
handlers.https = function (tlsSocket) { handlers.https = function (tlsSocket) {
console.log('Enccrypted', tlsSocket.encrypted, tlsSocket.remoteAddress, tlsSocket.remotePort);
if (!state.defaultHttpServer) { if (!state.defaultHttpServer) {
state.defaultHttpServer = require('http').createServer(function (req, res) { state.defaultHttpServer = require('http').createServer(function (req, res) {
console.log('[hit http/s server]'); console.log('[hit http/s server]');
@ -87,6 +88,27 @@ module.exports.assign = function (state, tun, cb) {
state.defaultHttpServer.emit('connection', tlsSocket); state.defaultHttpServer.emit('connection', tlsSocket);
}; };
function getNetConn(port) {
var netOpts = {
port: port
, host: '127.0.0.1'
, servername: tun.name
, name: tun.name
, serviceport: tun.serviceport
, data: tun.data
, remoteFamily: tun.family
, remoteAddress: tun.address
, remotePort: tun.port
};
var conn = net.createConnection(netOpts, function () {
// this will happen before 'data' or 'readable' is triggered
// We use the data from the netOpts object so that the createConnection function has
// the oppurtunity of removing/changing it if it wants/needs to handle it differently.
});
return conn;
}
if ('http' === tun.service || 'https' === tun.service) { if ('http' === tun.service || 'https' === tun.service) {
if (!tun.name) { if (!tun.name) {
cb(new Error("No routing information for ':tun_id'. Service '" + tun.service + "' is missing 'name'.")); cb(new Error("No routing information for ':tun_id'. Service '" + tun.service + "' is missing 'name'."));
@ -96,7 +118,7 @@ module.exports.assign = function (state, tun, cb) {
function redirectHttp(cb) { function redirectHttp(cb) {
var socketPair = require('socket-pair'); var socketPair = require('socket-pair');
conn = socketPair.create(function (err, other) { var conn = socketPair.create(function (err, other) {
if (err) { cb(err); return; } if (err) { cb(err); return; }
handlers.http(other); handlers.http(other);
cb(null, conn); cb(null, conn);
@ -130,23 +152,80 @@ module.exports.assign = function (state, tun, cb) {
return; return;
} }
function terminateTls(cb) { function defineProps(other, tun) {
Object.defineProperty(other, 'remoteFamily', {
enumerable: false,
configurable: true,
get: function() {
return tun.family;
}
});
Object.defineProperty(other, 'remoteAddress', {
enumerable: false,
configurable: true,
get: function() {
return tun.address;
}
});
Object.defineProperty(other, 'remotePort', {
enumerable: false,
configurable: true,
get: function() {
return parseInt(tun.port);
}
});
Object.defineProperty(other, 'localPort', {
enumerable: false,
configurable: true,
get: function() {
return parseInt(tun.serviceport);
}
});
}
function terminateTls(tun, cb) {
var socketPair = require('socket-pair'); var socketPair = require('socket-pair');
conn = socketPair.create(function (err, other) { var conn = socketPair.create(function (err, other) {
if (err) { cb(err); return; } if (err) { cb(err); return; }
//console.log('[hit tcp connection]', other.remoteFamily, other.remoteAddress, other.remotePort, other.localPort);
defineProps(other, tun);
//console.log('[hit tcp connection]', other.remoteFamily, other.remoteAddress, other.remotePort, other.localPort);
if (!state.greenlock) { if (!state.greenlock) {
state.greenlock = require('greenlock').create(state.greenlockConfig); state.greenlock = require('greenlock').create(state.greenlockConfig);
} }
if (!state.terminatorServer) { if (!state.terminatorServer) {
state.terminatorServer = require('tls').createServer(state.greenlock.tlsOptions, function (tlsSocket) { state.terminatorServer = require('tls').createServer(state.greenlock.tlsOptions, function (tlsSocket) {
console.log('[hit tls server]'); var Packer = require('proxy-packer');
if (err) { cb(err); return; } var addr = Packer.socketToAddr(tlsSocket);
handlers.https(tlsSocket); var id = Packer.addrToId(addr);
defineProps(tlsSocket, addr);
//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;
}
if (parseInt(conf.handler, 10)) {
// TODO http-proxy with proper headers and ws support
var conn = getNetConn(conf.handler);
conn.pipe(tlsSocket);
tlsSocket.pipe(conn);
}
var handler;
try {
handler = require(conf.handler);
handler(tlsSocket, addr, id);
} catch(e) {
handlers.https(tlsSocket, addr, id);
}
}); });
} }
console.log('[emitting tls connection]'); //console.log('[hit tcp connection]', other.remoteFamily, other.remoteAddress, other.remotePort, other.localPort);
state.terminatorServer.emit('connection', other); state.terminatorServer.emit('connection', other);
cb(null, conn); cb(null, conn);
}); });
@ -168,16 +247,16 @@ module.exports.assign = function (state, tun, cb) {
} }
console.log('Terminating TLS for', tun.name); console.log('Terminating TLS for', tun.name);
terminateTls(cb); terminateTls(tun, cb);
return true; return true;
}); });
if (!handled) { if (!handled) {
terminateTls(cb); terminateTls(tun, cb);
} }
return; return;
} }
return; /*
var portList = state.services[service]; var portList = state.services[service];
var port; var port;
port = portList[tun.name]; port = portList[tun.name];
@ -199,72 +278,5 @@ module.exports.assign = function (state, tun, cb) {
if (!port) { if (!port) {
port = portList['*']; port = portList['*'];
} }
*/
var createOpts = {
port: port
, host: '127.0.0.1'
, servername: tun.name
, name: tun.name
, serviceport: tun.serviceport
, data: tun.data
, remoteFamily: tun.family
, remoteAddress: tun.address
, remotePort: tun.port
};
var conn;
function handleNow(socket) {
var httpServer;
var tlsServer;
if ('https' === tun.service) {
if (!state.greenlock) {
state.greenlock = require('greenlock').create(state.greenlockConfig);
}
httpServer = require('http').createServer(function (req, res) {
console.log('[hit http/s server]');
res.end('Hello, Encrypted Tunnel World!');
});
tlsServer = require('tls').createServer(state.greenlock.tlsOptions, function (tlsSocket) {
console.log('[hit tls server]');
httpServer.emit('connection', tlsSocket);
});
tlsServer.emit('connection', socket);
} else {
httpServer = require('http').createServer(state.greenlock.middleware(function (req, res) {
console.log('[hit pure http server]');
res.end('Hello, Encrypted Tunnel World!');
}));
// http://aj.telebit.cloud/.well-known/acme-challenge/blah
httpServer.emit('connection', socket);
}
}
if ('aj.telebit.cloud' === tun.name) {
console.log('NEW CONNECTION to AJ\'s telebit could');
// For performance it may be better to use socket-pair, needs testing
var socketPair = require('socket-pair');
conn = socketPair.create(function (err, other) {
if (err) { console.error('[Error] ' + err.message); }
handleNow(other);
//if (createOpts.data) { conn.write(createOpts.data); }
});
/*
var streamPair = require('stream-pair');
var pair = streamPair.create();
conn = pair.other;
process.nextTick(function () {
if (createOpts.data) {
conn.write(createOpts.data);
}
});
*/
} else {
conn = net.createConnection(createOpts, function () {
// this will happen before 'data' or 'readable' is triggered
// We use the data from the createOpts object so that the createConnection function has
// the oppurtunity of removing/changing it if it wants/needs to handle it differently.
//if (createOpts.data) { conn.write(createOpts.data); }
});
}
cb(null, conn);
}; };