partial tunnel integration

This commit is contained in:
AJ ONeal 2016-10-11 17:20:10 -06:00
parent fa0990b02f
commit cd2fda3f2b
2 changed files with 137 additions and 11 deletions

View File

@ -1,20 +1,75 @@
'use strict';
module.exports.create = function (opts/*, servers*/) {
module.exports.create = function (opts, servers) {
// servers = { plainserver, server }
var tunnel = require('daplie-tunnel');
var Oauth3 = require('oauth3-cli');
var Tunnel = require('daplie-tunnel').create({
Oauth3: Oauth3
, PromiseA: opts.PromiseA
, CLI: {
init: function (/*rs, ws, state, options*/) {
// noop
}
}
}).Tunnel;
var stunnel = require('stunnel');
var killcount = 0;
/*
var Dup = {
write: function (chunk, encoding, cb) {
this.__my_socket.push(chunk, encoding);
cb();
}
, read: function (size) {
var x = this.__my_socket.read(size);
if (x) { this.push(x); }
}
, setTimeout: function () {
console.log('TODO implement setTimeout on Duplex');
}
};
return tunnel.token({
var httpServer = require('http').createServer(function (req, res) {
console.log('req.socket.encrypted', req.socket.encrypted);
res.end('Hello, tunneled World!');
});
var tlsServer = require('tls').createServer(opts.httpsOptions, function (tlsSocket) {
console.log('tls connection');
// things get a little messed up here
httpServer.emit('connection', tlsSocket);
// try again
//servers.server.emit('connection', tlsSocket);
});
*/
process.on('SIGINT', function () {
killcount += 1;
console.log('[quit] closing http and https servers');
if (killcount >= 3) {
process.exit(1);
}
if (servers.server) {
servers.server.close();
}
if (servers.insecureServer) {
servers.insecureServer.close();
}
});
return Tunnel.token({
refreshToken: opts.refreshToken
, email: opts.email
, domains: [ opts.servername ]
}).then(function (result) {
// { jwt, tunnelUrl }
stunnel.connect({
return stunnel.connect({
token: result.jwt
, stunneld: result.tunnelUrl
// XXX TODO BUG // this is just for testing
, insecure: /*opts.insecure*/ true
, locals: [
{ protocol: 'https'
, hostname: opts.servername
@ -25,6 +80,57 @@ module.exports.create = function (opts/*, servers*/) {
, port: opts.insecurePort || opts.port
}
]
// a simple passthru is proving to not be so simple
, net: require('net') /*
{
createConnection: function (info, cb) {
// data is the hello packet / first chunk
// info = { data, servername, port, host, remoteAddress: { family, address, port } }
var myDuplex = new (require('stream').Duplex)();
var myDuplex2 = new (require('stream').Duplex)();
// duplex = { write, push, end, events: [ 'readable', 'data', 'error', 'end' ] };
myDuplex2.__my_socket = myDuplex;
myDuplex.__my_socket = myDuplex2;
myDuplex2._write = Dup.write;
myDuplex2._read = Dup.read;
myDuplex._write = Dup.write;
myDuplex._read = Dup.read;
myDuplex.remoteFamily = info.remoteFamily;
myDuplex.remoteAddress = info.remoteAddress;
myDuplex.remotePort = info.remotePort;
// socket.local{Family,Address,Port}
myDuplex.localFamily = 'IPv4';
myDuplex.localAddress = '127.0.01';
myDuplex.localPort = info.port;
myDuplex.setTimeout = Dup.setTimeout;
// this doesn't seem to work so well
//servers.server.emit('connection', myDuplex);
// try a little more manual wrapping / unwrapping
var firstByte = info.data[0];
if (firstByte < 32 || firstByte >= 127) {
tlsServer.emit('connection', myDuplex);
}
else {
httpServer.emit('connection', myDuplex);
}
if (cb) {
process.nextTick(cb);
}
return myDuplex2;
}
}
//*/
});
});
};

View File

@ -3,6 +3,7 @@
//var PromiseA = global.Promise;
var PromiseA = require('bluebird');
var tls = require('tls');
var https = require('httpolyglot');
var http = require('http');
var fs = require('fs');
@ -107,6 +108,7 @@ function createServer(port, pubdir, content, opts) {
// returns an instance of node-letsencrypt with additional helper methods
var webrootPath = require('os').tmpdir();
var leChallengeFs = require('le-challenge-fs').create({ webrootPath: webrootPath });
//var leChallengeSni = require('le-challenge-sni').create({ webrootPath: webrootPath });
var leChallengeDns = require('le-challenge-dns').create({ ttl: 1 });
var lex = require('letsencrypt-express').create({
// set to https://acme-v01.api.letsencrypt.org/directory in production
@ -116,10 +118,10 @@ function createServer(port, pubdir, content, opts) {
//
, challenges: {
'http-01': leChallengeFs
, 'tls-sni-01': leChallengeFs
, 'tls-sni-01': leChallengeFs // leChallengeSni
, 'dns-01': leChallengeDns
}
, challengeType: 'dns-01'
, challengeType: (opts.tunnel ? 'http-01' : 'dns-01')
, store: require('le-store-certbot').create({ webrootPath: webrootPath })
, webrootPath: webrootPath
@ -129,7 +131,20 @@ function createServer(port, pubdir, content, opts) {
, approveDomains: approveDomains
});
opts.httpsOptions.SNICallback = lex.httpsOptions.SNICallback;
var secureContext;
opts.httpsOptions.SNICallback = function (servername, cb ) {
console.log('[https] servername', servername);
if ('localhost.daplie.com' === servername) {
if (!secureContext) {
secureContext = tls.createSecureContext(opts.httpsOptions);
}
cb(null, secureContext);
return;
}
lex.httpsOptions.SNICallback(servername, cb);
};
var server = https.createServer(opts.httpsOptions);
server.on('error', function (err) {
@ -211,7 +226,6 @@ function run() {
var pubdir = path.resolve(argv.d || argv._[1] || process.cwd());
var content = argv.c;
var letsencryptHost = argv['letsencrypt-certs'];
var tls = require('tls');
if (argv.V || argv.version || argv.v) {
if (argv.v) {
@ -239,6 +253,7 @@ function run() {
var peerCa;
var p;
opts.PromiseA = PromiseA;
opts.httpsOptions.SNICallback = function (servername, cb) {
if (!secureContext) {
secureContext = tls.createSecureContext(opts.httpsOptions);
@ -354,7 +369,7 @@ function run() {
};
opts.redirectApp = require('redirect-https')(opts.redirectOptions);
return createServer(port, pubdir, content, opts).then(function () {
return createServer(port, pubdir, content, opts).then(function (servers) {
var msg;
var p;
var httpsUrl;
@ -424,8 +439,13 @@ function run() {
}
});
}
else {
require('./lib/tunnel.js').create(opts);
else if (!opts.tunnel) {
console.info("External IP address does not match local IP address.");
console.info("Use --tunnel to allow the people of the Internet to access your server.");
}
if (opts.tunnel) {
require('./lib/tunnel.js').create(opts, servers);
}
Object.keys(opts.ifaces).forEach(function (iname) {