partial tunnel integration
This commit is contained in:
parent
fa0990b02f
commit
cd2fda3f2b
114
lib/tunnel.js
114
lib/tunnel.js
|
@ -1,20 +1,75 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports.create = function (opts/*, servers*/) {
|
module.exports.create = function (opts, servers) {
|
||||||
// servers = { plainserver, server }
|
// 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 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
|
refreshToken: opts.refreshToken
|
||||||
, email: opts.email
|
, email: opts.email
|
||||||
, domains: [ opts.servername ]
|
, domains: [ opts.servername ]
|
||||||
}).then(function (result) {
|
}).then(function (result) {
|
||||||
// { jwt, tunnelUrl }
|
// { jwt, tunnelUrl }
|
||||||
stunnel.connect({
|
return stunnel.connect({
|
||||||
token: result.jwt
|
token: result.jwt
|
||||||
, stunneld: result.tunnelUrl
|
, stunneld: result.tunnelUrl
|
||||||
|
// XXX TODO BUG // this is just for testing
|
||||||
|
, insecure: /*opts.insecure*/ true
|
||||||
, locals: [
|
, locals: [
|
||||||
{ protocol: 'https'
|
{ protocol: 'https'
|
||||||
, hostname: opts.servername
|
, hostname: opts.servername
|
||||||
|
@ -25,6 +80,57 @@ module.exports.create = function (opts/*, servers*/) {
|
||||||
, port: opts.insecurePort || opts.port
|
, 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//*/
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
34
serve.js
34
serve.js
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
//var PromiseA = global.Promise;
|
//var PromiseA = global.Promise;
|
||||||
var PromiseA = require('bluebird');
|
var PromiseA = require('bluebird');
|
||||||
|
var tls = require('tls');
|
||||||
var https = require('httpolyglot');
|
var https = require('httpolyglot');
|
||||||
var http = require('http');
|
var http = require('http');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
@ -107,6 +108,7 @@ function createServer(port, pubdir, content, opts) {
|
||||||
// returns an instance of node-letsencrypt with additional helper methods
|
// returns an instance of node-letsencrypt with additional helper methods
|
||||||
var webrootPath = require('os').tmpdir();
|
var webrootPath = require('os').tmpdir();
|
||||||
var leChallengeFs = require('le-challenge-fs').create({ webrootPath: webrootPath });
|
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 leChallengeDns = require('le-challenge-dns').create({ ttl: 1 });
|
||||||
var lex = require('letsencrypt-express').create({
|
var lex = require('letsencrypt-express').create({
|
||||||
// set to https://acme-v01.api.letsencrypt.org/directory in production
|
// set to https://acme-v01.api.letsencrypt.org/directory in production
|
||||||
|
@ -116,10 +118,10 @@ function createServer(port, pubdir, content, opts) {
|
||||||
//
|
//
|
||||||
, challenges: {
|
, challenges: {
|
||||||
'http-01': leChallengeFs
|
'http-01': leChallengeFs
|
||||||
, 'tls-sni-01': leChallengeFs
|
, 'tls-sni-01': leChallengeFs // leChallengeSni
|
||||||
, 'dns-01': leChallengeDns
|
, 'dns-01': leChallengeDns
|
||||||
}
|
}
|
||||||
, challengeType: 'dns-01'
|
, challengeType: (opts.tunnel ? 'http-01' : 'dns-01')
|
||||||
, store: require('le-store-certbot').create({ webrootPath: webrootPath })
|
, store: require('le-store-certbot').create({ webrootPath: webrootPath })
|
||||||
, webrootPath: webrootPath
|
, webrootPath: webrootPath
|
||||||
|
|
||||||
|
@ -129,7 +131,20 @@ function createServer(port, pubdir, content, opts) {
|
||||||
|
|
||||||
, approveDomains: approveDomains
|
, 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);
|
var server = https.createServer(opts.httpsOptions);
|
||||||
|
|
||||||
server.on('error', function (err) {
|
server.on('error', function (err) {
|
||||||
|
@ -211,7 +226,6 @@ function run() {
|
||||||
var pubdir = path.resolve(argv.d || argv._[1] || process.cwd());
|
var pubdir = path.resolve(argv.d || argv._[1] || process.cwd());
|
||||||
var content = argv.c;
|
var content = argv.c;
|
||||||
var letsencryptHost = argv['letsencrypt-certs'];
|
var letsencryptHost = argv['letsencrypt-certs'];
|
||||||
var tls = require('tls');
|
|
||||||
|
|
||||||
if (argv.V || argv.version || argv.v) {
|
if (argv.V || argv.version || argv.v) {
|
||||||
if (argv.v) {
|
if (argv.v) {
|
||||||
|
@ -239,6 +253,7 @@ function run() {
|
||||||
var peerCa;
|
var peerCa;
|
||||||
var p;
|
var p;
|
||||||
|
|
||||||
|
opts.PromiseA = PromiseA;
|
||||||
opts.httpsOptions.SNICallback = function (servername, cb) {
|
opts.httpsOptions.SNICallback = function (servername, cb) {
|
||||||
if (!secureContext) {
|
if (!secureContext) {
|
||||||
secureContext = tls.createSecureContext(opts.httpsOptions);
|
secureContext = tls.createSecureContext(opts.httpsOptions);
|
||||||
|
@ -354,7 +369,7 @@ function run() {
|
||||||
};
|
};
|
||||||
opts.redirectApp = require('redirect-https')(opts.redirectOptions);
|
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 msg;
|
||||||
var p;
|
var p;
|
||||||
var httpsUrl;
|
var httpsUrl;
|
||||||
|
@ -424,8 +439,13 @@ function run() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else if (!opts.tunnel) {
|
||||||
require('./lib/tunnel.js').create(opts);
|
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) {
|
Object.keys(opts.ifaces).forEach(function (iname) {
|
||||||
|
|
Loading…
Reference in New Issue