このコミットが含まれているのは:
AJ ONeal 2016-09-30 18:03:41 -04:00
コミット 2825afbb13
10個のファイルの変更298行の追加5行の削除

2
.gitignore vendored
ファイルの表示

@ -1,3 +1,5 @@
node_modules.*
# Logs
logs
*.log

91
bin/stunneld.js 実行可能ファイル
ファイルの表示

@ -0,0 +1,91 @@
#!/usr/bin/env node
(function () {
'use strict';
var pkg = require('../package.json');
var program = require('commander');
var url = require('url');
var stunneld = require('../wstunneld.js');
function collectProxies(val, memo) {
var vals = val.split(/,/g);
vals.map(function (location) {
// http:john.example.com:3000
// http://john.example.com:3000
var parts = location.split(':');
parts[0] = parts[0].toLowerCase();
parts[1] = parts[1].toLowerCase().replace(/(\/\/)?/, '') || '*';
parts[2] = parseInt(parts[2], 10) || 0;
if (!parts[2]) {
// TODO grab OS list of standard ports?
if ('http' === parts[0]) {
parts[2] = 80;
}
else if ('https' === parts[0]) {
parts[2] = 443;
}
else {
throw new Error("port must be specified - ex: tls:*:1337");
}
}
return {
protocol: parts[0]
, hostname: parts[1]
, port: parts[2]
};
}).forEach(function (val) {
memo.push(val);
});
return memo;
}
program
.version(pkg.version)
//.command('jsurl <url>')
.arguments('<url>')
.action(function (url) {
program.url = url;
})
.option('-k --insecure', 'Allow TLS connections to stunneld without valid certs (rejectUnauthorized: false)')
.option('--locals <LINE>', 'comma separated list of <proto>:<//><servername>:<port> to which matching incoming http and https should forward (reverse proxy). Ex: https://john.example.com,tls:*:1337', collectProxies, [ ]) // --reverse-proxies
.option('--stunneld <URL>', 'the domain (or ip address) at which you are running stunneld.js (the proxy)') // --proxy
.option('--secret <STRING>', 'the same secret used by stunneld (used for JWT authentication)')
.option('--token <STRING>', 'a pre-generated token for use with stunneld (instead of generating one with --secret)')
.parse(process.argv)
;
program.stunneld = program.stunneld || 'wss://pokemap.hellabit.com:3000';
var jwt = require('jsonwebtoken');
var domainsMap = {};
var tokenData = {
name: null
, domains: null
};
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 : '');
program.locals.forEach(function (proxy) {
domainsMap[proxy.hostname] = true;
});
tokenData.domains = Object.keys(domainsMap);
tokenData.name = tokenData.domains[0];
program.services = {};
program.locals.forEach(function (proxy) {
//program.services = { 'ssh': 22, 'http': 80, 'https': 443 };
program.services[proxy.protocol] = proxy.port;
});
program.token = program.token || jwt.sign(tokenData, program.secret || 'shhhhh');
stunnel.connect(program);
}());

ファイルの表示

@ -1,8 +1,13 @@
{
"name": "tunnel-server",
"version": "1.0.0",
"description": "A naive tcp tunnel server",
"main": "serve.js",
"name": "stunneld",
"version": "0.8.0",
"description": "A pure-JavaScript tunnel daemon for http and https similar to a localtunnel.me server, but uses TLS (SSL) with ServerName Indication (SNI) over https to work even in harsh network conditions such as in student dorms and behind HOAs, corporate firewalls, public libraries, airports, airplanes, etc. Can also tunnel tls and plain tcp.",
"main": "wstunneld.js",
"bin": {
"jstunneld": "bin/stunneld.js",
"stunneld.js": "bin/stunneld.js",
"stunneld-js": "bin/stunneld.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
@ -11,8 +16,28 @@
"url": "git+https://github.com/Daplie/node-tunnel-server.git"
},
"keywords": [
"server",
"daemon",
"tcp",
"tunnel"
"tls",
"http",
"https",
"sni",
"servername",
"indication",
"stunnel",
"secure",
"securetunnel",
"secure-tunnel",
"tunnel",
"localtunnel",
"localtunnel.me",
"proxy",
"reverse",
"reverse-proxy",
"reverseproxy",
"vpn",
"sni"
],
"author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)",
"license": "(MIT OR Apache-2.0)",

ファイルの表示

ファイルの表示

59
snippets/serve80.js ノーマルファイル
ファイルの表示

@ -0,0 +1,59 @@
'use strict';
var net = require('net');
var tls = require('tls');
var http = require('http');
var https = require('https');
var sni = require('sni');
var http80 = http.createServer(function (req, res) {
res.end('Happy Day!');
});
var tcp80 = net.createServer(function (client) {
http80.emit('connection', client);
});
tcp80.listen(80, function () {
console.log('listening on 80');
});
var tlsOpts = require('localhost.daplie.com-certificates').merge({});
var https443 = https.createServer(tlsOpts, function (req, res) {
res.end('Happy Encrypted Day!');
});
var tls443 = tls.createServer(tlsOpts, function (socket) {
socket.on('data', function (chunk) {
console.log('chunk', chunk.toString());
});
});
var tcp443 = net.createServer(function (client) {
//tls443.emit('connection', client); // no go
//return;
client.once('data', function (chunk) {
var servername = sni(chunk);
console.log('servername:', servername);
//client.push(chunk);
https443.emit('connection', client);
//tls443.emit('connection', client); // no go
//client.pause();
process.nextTick(function () {
//client.emit('data', chunk);
client.push(chunk);
client.emit('readable', chunk);
//client.resume();
});
//client.resume();
});
});
tcp443.listen(443, function () {
console.log('listening on 443');
});

33
snippets/tcp-spy.js ノーマルファイル
ファイルの表示

@ -0,0 +1,33 @@
'use strict';
var net = require('net');
var http = require('http');
var http80 = http.createServer(function (req, res) {
res.end('Hello, World!');
});
var tcp80 = net.createServer(function (socket) {
socket.once('data', function (chunk) {
if (/http\/1/i.test(chunk.toString())) {
console.log("looks like http, continue");
http80.emit('connection', socket);
} else {
console.log("looks like tcp, die");
socket.end();
}
socket.pause();
process.nextTick(function () {
socket.emit('data', chunk);
socket.resume();
});
});
});
tcp80.listen(80, function () {
console.log('listening on 80');
});

47
snippets/tls-spy.js ノーマルファイル
ファイルの表示

@ -0,0 +1,47 @@
'use strict';
var net = require('net');
var tls = require('tls');
var http = require('http');
var sni = require('sni');
var https = require('https');
var tlsOpts = require('localhost.daplie.com-certificates').merge({});
var http80 = http.createServer(function (req, res) {
res.end('Hello, World!');
});
var https443 = https.createServer(tlsOpts, function (req, res) {
res.end('Hello, Encrypted World!');
});
var tcp3000 = net.createServer(function (socket) {
socket.once('data', function (chunk) {
if (/http\/1/i.test(chunk.toString())) {
console.log("looks like http, continue");
http80.emit('connection', socket);
} else {
console.log("doesn't look like http, try tls");
https443.emit('connection', socket);
var tlsSocket = new tls.TLSSocket(socket, { secureContext: tls.createSecureContext(tlsOpts) });
tlsSocket.on('data', function (chunk) {
console.log('chunk', chunk);
});
socket.emit('connect');
//http80.emit('connection', socket);
}
socket.pause();
process.nextTick(function () {
socket.emit('data', chunk);
socket.resume();
});
});
});
tcp3000.listen(3000, function () {
console.log('listening on 3000');
});

36
snippets/wss.js ノーマルファイル
ファイルの表示

@ -0,0 +1,36 @@
(function () {
'use strict';
function app(req, res) {
console.log('hello');
res.send({ msg: "hello" });
}
var tlsOpts = require('localhost.daplie.com-certificates').merge({});
var url = require('url');
var WebSocketServer = require('ws').Server;
var server = require('https').createServer(tlsOpts, app);
var wss = new WebSocketServer({ server: server });
//var express = require('express');
//var app = express();
var port = 3000;
wss.on('connection', function connection(ws) {
console.log('connection');
var location = url.parse(ws.upgradeReq.url, true);
console.log('location.query.access_token');
console.log(location.query.access_token);
// you might use location.query.access_token to authenticate or share sessions
// or ws.upgradeReq.headers.cookie (see http://stackoverflow.com/a/16395220/151312)
ws.on('message', function incoming(message) {
console.log('received: %s', message);
});
//ws.send('something');
});
server.listen(port, function () { console.log('Listening on ' + server.address().port); });
}());

ファイルの表示