forked from coolaj86/goldilocks.js
		
	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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user