changed method for mapping services to local ports
This commit is contained in:
parent
a9326c3eb0
commit
ae15111b0f
102
bin/stunnel.js
102
bin/stunnel.js
|
@ -13,7 +13,6 @@ function collectDomains(val, memo) {
|
|||
|
||||
function parseProxy(location) {
|
||||
// john.example.com
|
||||
// https:3443
|
||||
// http:john.example.com:3000
|
||||
// http://john.example.com:3000
|
||||
var parts = location.split(':');
|
||||
|
@ -144,19 +143,11 @@ function connectTunnel() {
|
|||
}
|
||||
};
|
||||
|
||||
program.locals.forEach(function (proxy) {
|
||||
var port = proxy.port;
|
||||
if (!proxy.port) {
|
||||
if ('http' === proxy.protocol) {
|
||||
port = hasHttp;
|
||||
}
|
||||
else if ('https' === proxy.protocol) {
|
||||
port = hasHttps;
|
||||
}
|
||||
}
|
||||
if (proxy.protocol) {
|
||||
console.info('[local proxy]', proxy.protocol + '://' + proxy.hostname + ' => ' + port);
|
||||
}
|
||||
Object.keys(program.services).forEach(function (protocol) {
|
||||
var subServices = program.services[protocol];
|
||||
Object.keys(subServices).forEach(function (hostname) {
|
||||
console.info('[local proxy]', protocol + '://' + hostname + ' => ' + subServices[hostname]);
|
||||
});
|
||||
});
|
||||
console.info('');
|
||||
|
||||
|
@ -179,22 +170,22 @@ function rawTunnel() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!program.token) {
|
||||
var jwt = require('jsonwebtoken');
|
||||
var tokenData = {
|
||||
domains: null
|
||||
domains: Object.keys(domainsMap).filter(Boolean)
|
||||
};
|
||||
var location = url.parse(program.stunneld);
|
||||
|
||||
program.token = jwt.sign(tokenData, program.secret);
|
||||
}
|
||||
|
||||
var location = url.parse(program.stunneld);
|
||||
if (!location.protocol || /\./.test(location.protocol)) {
|
||||
program.stunneld = 'wss://' + program.stunneld;
|
||||
location = url.parse(program.stunneld);
|
||||
}
|
||||
program.stunneld = location.protocol + '//' + location.hostname + (location.port ? ':' + location.port : '');
|
||||
|
||||
tokenData.domains = Object.keys(domainsMap).filter(Boolean);
|
||||
|
||||
program.token = program.token || jwt.sign(tokenData, program.secret);
|
||||
|
||||
connectTunnel();
|
||||
}
|
||||
|
||||
|
@ -234,45 +225,50 @@ function daplieTunnel() {
|
|||
}
|
||||
|
||||
var domainsMap = {};
|
||||
var hasHttp;
|
||||
var hasHttps;
|
||||
var services = {};
|
||||
|
||||
program.locals = program.locals || [];
|
||||
program.locals = program.locals.concat(program.domains || []);
|
||||
program.locals.forEach(function (proxy) {
|
||||
if ('*' === proxy.hostname) {
|
||||
if ('http' === proxy.protocol) {
|
||||
hasHttp = proxy.port;
|
||||
}
|
||||
else if ('https' === proxy.protocol) {
|
||||
hasHttps = proxy.port;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!hasHttp) {
|
||||
program.locals.push({
|
||||
protocol: 'http'
|
||||
, hostname: '*'
|
||||
, port: 8443
|
||||
});
|
||||
hasHttp = 8443;
|
||||
}
|
||||
if (!hasHttps) {
|
||||
program.locals.push({
|
||||
protocol: 'https'
|
||||
, hostname: '*'
|
||||
, port: 8443
|
||||
});
|
||||
hasHttps = 8443;
|
||||
}
|
||||
program.locals = (program.locals || []).concat(program.domains || []);
|
||||
program.locals.forEach(function (proxy) {
|
||||
// Create a map from which we can derive a list of all domains we want forwarded to us.
|
||||
if (proxy.hostname && proxy.hostname !== '*') {
|
||||
domainsMap[proxy.hostname] = true;
|
||||
}
|
||||
|
||||
// Create a map of which port different protocols should be forwarded to, allowing for specific
|
||||
// domains to go to different ports if need be (though that only works for HTTP and HTTPS).
|
||||
if (proxy.protocol && proxy.port) {
|
||||
services[proxy.protocol] = services[proxy.protocol] || {};
|
||||
|
||||
if (/http/.test(proxy.protocol) && proxy.hostname && proxy.hostname !== '*') {
|
||||
services[proxy.protocol][proxy.hostname] = proxy.port;
|
||||
}
|
||||
else {
|
||||
if (services[proxy.protocol]['*'] && services[proxy.protocol]['*'] !== proxy.port) {
|
||||
console.error('cannot forward generic', proxy.protocol, 'traffic to multiple ports');
|
||||
process.exit(1);
|
||||
}
|
||||
else {
|
||||
services[proxy.protocol]['*'] = proxy.port;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (domainsMap.hasOwnProperty('*')) {
|
||||
delete domainsMap['*'];
|
||||
//domainsMap['*'] = false;
|
||||
|
||||
if (Object.keys(domainsMap).length === 0) {
|
||||
console.error('no domains specified');
|
||||
process.exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we have generic ports for HTTP and HTTPS
|
||||
services.https = services.https || {};
|
||||
services.https['*'] = services.https['*'] || 8443;
|
||||
|
||||
services.http = services.http || {};
|
||||
services.http['*'] = services.http['*'] || services.https['*'];
|
||||
|
||||
program.services = services;
|
||||
|
||||
if (!(program.secret || program.token) && !program.stunneld) {
|
||||
daplieTunnel();
|
||||
}
|
||||
|
|
28
wsclient.js
28
wsclient.js
|
@ -7,13 +7,6 @@ var Packer = require('tunnel-packer');
|
|||
var authenticated = false;
|
||||
|
||||
function run(copts) {
|
||||
// TODO pair with hostname / sni
|
||||
copts.services = {};
|
||||
copts.locals.forEach(function (proxy) {
|
||||
//program.services = { 'ssh': 22, 'http': 80, 'https': 443 };
|
||||
copts.services[proxy.protocol] = proxy.port;
|
||||
});
|
||||
|
||||
var tunnelUrl = copts.stunneld.replace(/\/$/, '') + '/?access_token=' + copts.token;
|
||||
var wstunneler;
|
||||
var localclients = {};
|
||||
|
@ -26,9 +19,10 @@ function run(copts) {
|
|||
onmessage: function (opts) {
|
||||
var net = copts.net || require('net');
|
||||
var cid = Packer.addrToId(opts);
|
||||
var service = opts.service;
|
||||
var port = copts.services[service];
|
||||
var service = opts.service.toLowerCase();
|
||||
var portList = copts.services[service];
|
||||
var servername;
|
||||
var port;
|
||||
var str;
|
||||
var m;
|
||||
|
||||
|
@ -39,7 +33,12 @@ function run(copts) {
|
|||
localclients[cid].write(opts.data);
|
||||
return;
|
||||
}
|
||||
else if ('http' === service) {
|
||||
if (!portList) {
|
||||
handlers._onLocalError(cid, opts, new Error("unsupported service '" + service + "'"));
|
||||
return;
|
||||
}
|
||||
|
||||
if ('http' === service) {
|
||||
str = opts.data.toString();
|
||||
m = str.match(/(?:^|[\r\n])Host: ([^\r\n]+)[\r\n]*/im);
|
||||
servername = (m && m[1].toLowerCase() || '').split(':')[0];
|
||||
|
@ -48,20 +47,19 @@ function run(copts) {
|
|||
servername = sni(opts.data);
|
||||
}
|
||||
else {
|
||||
handlers._onLocalError(cid, opts, new Error("unsupported service '" + service + "'"));
|
||||
return;
|
||||
servername = '*';
|
||||
}
|
||||
|
||||
if (!servername) {
|
||||
console.info("[error] missing servername for '" + cid + "'", opts.data.byteLength);
|
||||
//console.warn(opts.data.toString());
|
||||
wstunneler.send(Packer.pack(opts, null, 'error'), { binary: true });
|
||||
handlers._onLocalError(cid, opts, new Error("missing servername for '" + cid + "' " + opts.data.byteLength));
|
||||
return;
|
||||
}
|
||||
port = portList[servername] || portList['*'];
|
||||
|
||||
console.info("[connect] new client '" + cid + "' for '" + servername + "' (" + (handlers._numClients() + 1) + " clients)");
|
||||
|
||||
console.log('port', port, opts.port, service, copts.services);
|
||||
console.log('port', port, opts.port, service, portList);
|
||||
localclients[cid] = net.createConnection({
|
||||
port: port
|
||||
, host: '127.0.0.1'
|
||||
|
|
Loading…
Reference in New Issue