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';
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
//*/
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
34
serve.js
34
serve.js
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue