forked from coolaj86/telebit.js
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
3fa6d15848 | |||
73c4444b51 | |||
687b2a3567 | |||
fb8aa998b3 | |||
4a1f020100 | |||
e72a5f1f56 | |||
3c068debc0 | |||
bd8d32d8ec | |||
78407f2a3e |
12
README.md
12
README.md
@ -36,7 +36,7 @@ Examples
|
|||||||
|
|
||||||
You do this:
|
You do this:
|
||||||
|
|
||||||
curl -fsSL https://get.telebit.io | bash
|
curl -fsSL https://get.telebit.cloud | bash
|
||||||
|
|
||||||
You get this:
|
You get this:
|
||||||
|
|
||||||
@ -70,19 +70,19 @@ Mac & Linux
|
|||||||
Open Terminal and run this install script:
|
Open Terminal and run this install script:
|
||||||
|
|
||||||
```
|
```
|
||||||
curl -fsSL https://get.telebit.io | bash
|
curl -fsSL https://get.telebit.cloud | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
```
|
```
|
||||||
bash <( curl -fsSL https://get.telebit.io )
|
bash <( curl -fsSL https://get.telebit.cloud )
|
||||||
```
|
```
|
||||||
|
|
||||||
<small>
|
<small>
|
||||||
Note: **fish**, **zsh**, and other **non-bash** users should do this
|
Note: **fish**, **zsh**, and other **non-bash** users should do this
|
||||||
|
|
||||||
```
|
```
|
||||||
curl -fsSL https://get.telebit.io/ > get.sh; bash get.sh
|
curl -fsSL https://get.telebit.cloud/ > get.sh; bash get.sh
|
||||||
```
|
```
|
||||||
</small>
|
</small>
|
||||||
-->
|
-->
|
||||||
@ -98,7 +98,7 @@ What does the installer do?
|
|||||||
* `~/.config/telebit/telebit.yml`
|
* `~/.config/telebit/telebit.yml`
|
||||||
* `~/.local/share/telebit`
|
* `~/.local/share/telebit`
|
||||||
|
|
||||||
Of course, feel free to inspect it before you run it: `curl -fsSL https://get.telebit.io`
|
Of course, feel free to inspect it before you run it: `curl -fsSL https://get.telebit.cloud`
|
||||||
|
|
||||||
**You can customize the installation**:
|
**You can customize the installation**:
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ export TELEBIT_USERSPACE=no # install as a system service (launchd
|
|||||||
export TELEBIT_PATH=/opt/telebit
|
export TELEBIT_PATH=/opt/telebit
|
||||||
export TELEBIT_USER=telebit
|
export TELEBIT_USER=telebit
|
||||||
export TELEBIT_GROUP=telebit
|
export TELEBIT_GROUP=telebit
|
||||||
curl -fsSL https://get.telebit.io/ | bash
|
curl -fsSL https://get.telebit.cloud/ | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
That will change the bundled version of node.js is bundled with Telebit Relay
|
That will change the bundled version of node.js is bundled with Telebit Relay
|
||||||
|
@ -790,6 +790,9 @@ var parsers = {
|
|||||||
answers[parts[0]] = parts[1];
|
answers[parts[0]] = parts[1];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (answers.relay) {
|
||||||
|
console.info("using --relay " + answers.relay);
|
||||||
|
}
|
||||||
// things that aren't straight-forward copy-over
|
// things that aren't straight-forward copy-over
|
||||||
if (!answers.advanced && !answers.relay) {
|
if (!answers.advanced && !answers.relay) {
|
||||||
answers.relay = 'telebit.cloud';
|
answers.relay = 'telebit.cloud';
|
||||||
|
@ -52,10 +52,15 @@ function _connect(state) {
|
|||||||
+ "(" + clientHandlers.count() + " clients)");
|
+ "(" + clientHandlers.count() + " clients)");
|
||||||
|
|
||||||
conn.tunnelCid = cid;
|
conn.tunnelCid = cid;
|
||||||
conn.tunnelRead = tun.data.byteLength;
|
if (tun.data) {
|
||||||
conn.tunnelWritten = 0;
|
conn.tunnelRead = tun.data.byteLength;
|
||||||
|
} else {
|
||||||
|
conn.tunnelRead = 0;
|
||||||
|
}
|
||||||
|
conn.tunnelWritten = 0;
|
||||||
|
|
||||||
conn.on('data', function onLocalData(chunk) {
|
conn.on('data', function onLocalData(chunk) {
|
||||||
|
//var chunk = conn.read();
|
||||||
if (conn.tunnelClosing) {
|
if (conn.tunnelClosing) {
|
||||||
console.warn("[onLocalData] received data for '"+cid+"' over socket after connection was ended");
|
console.warn("[onLocalData] received data for '"+cid+"' over socket after connection was ended");
|
||||||
return;
|
return;
|
||||||
@ -67,8 +72,10 @@ function _connect(state) {
|
|||||||
// down the data we are getting to send over. We also want to pause all active connections
|
// down the data we are getting to send over. We also want to pause all active connections
|
||||||
// if any connections are paused to make things more fair so one connection doesn't get
|
// if any connections are paused to make things more fair so one connection doesn't get
|
||||||
// stuff waiting for all other connections to finish because it tried writing near the border.
|
// stuff waiting for all other connections to finish because it tried writing near the border.
|
||||||
var bufSize = wsHandlers.sendMessage(Packer.pack(tun, chunk));
|
var bufSize = wsHandlers.sendMessage(Packer.packHeader(tun, chunk));
|
||||||
if (pausedClients.length || bufSize > 1024*1024) {
|
// Sending 2 messages instead of copying the buffer
|
||||||
|
var bufSize2 = wsHandlers.sendMessage(chunk);
|
||||||
|
if (pausedClients.length || (bufSize + bufSize2) > 1024*1024) {
|
||||||
// console.log('[onLocalData] paused connection', cid, 'to allow websocket to catch up');
|
// console.log('[onLocalData] paused connection', cid, 'to allow websocket to catch up');
|
||||||
conn.pause();
|
conn.pause();
|
||||||
pausedClients.push(conn);
|
pausedClients.push(conn);
|
||||||
@ -80,14 +87,15 @@ function _connect(state) {
|
|||||||
console.info("[onLocalEnd] connection '" + cid + "' ended, will probably close soon");
|
console.info("[onLocalEnd] connection '" + cid + "' ended, will probably close soon");
|
||||||
conn.tunnelClosing = true;
|
conn.tunnelClosing = true;
|
||||||
if (!sentEnd) {
|
if (!sentEnd) {
|
||||||
wsHandlers.sendMessage(Packer.pack(tun, null, 'end'));
|
wsHandlers.sendMessage(Packer.packHeader(tun, null, 'end'));
|
||||||
sentEnd = true;
|
sentEnd = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
conn.on('error', function onLocalError(err) {
|
conn.on('error', function onLocalError(err) {
|
||||||
console.info("[onLocalError] connection '" + cid + "' errored:", err);
|
console.info("[onLocalError] connection '" + cid + "' errored:", err);
|
||||||
if (!sentEnd) {
|
if (!sentEnd) {
|
||||||
wsHandlers.sendMessage(Packer.pack(tun, {message: err.message, code: err.code}, 'error'));
|
var packBody = true;
|
||||||
|
wsHandlers.sendMessage(Packer.packHeader(tun, {message: err.message, code: err.code}, 'error', packBody));
|
||||||
sentEnd = true;
|
sentEnd = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -95,7 +103,7 @@ function _connect(state) {
|
|||||||
delete localclients[cid];
|
delete localclients[cid];
|
||||||
console.log('[onLocalClose] closed "' + cid + '" read:'+conn.tunnelRead+', wrote:'+conn.tunnelWritten+' (' + clientHandlers.count() + ' clients)');
|
console.log('[onLocalClose] closed "' + cid + '" read:'+conn.tunnelRead+', wrote:'+conn.tunnelWritten+' (' + clientHandlers.count() + ' clients)');
|
||||||
if (!sentEnd) {
|
if (!sentEnd) {
|
||||||
wsHandlers.sendMessage(Packer.pack(tun, null, hadErr && 'error' || 'end'));
|
wsHandlers.sendMessage(Packer.packHeader(tun, null, hadErr && 'error' || 'end'));
|
||||||
sentEnd = true;
|
sentEnd = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -119,11 +127,13 @@ function _connect(state) {
|
|||||||
conn.tunnelRead += opts.data.byteLength;
|
conn.tunnelRead += opts.data.byteLength;
|
||||||
|
|
||||||
if (!conn.remotePaused && conn.bufferSize > 1024*1024) {
|
if (!conn.remotePaused && conn.bufferSize > 1024*1024) {
|
||||||
wsHandlers.sendMessage(Packer.pack(opts, conn.tunnelRead, 'pause'));
|
var packBody = true;
|
||||||
|
wsHandlers.sendMessage(Packer.packHeader(opts, conn.tunnelRead, 'pause', packBody));
|
||||||
conn.remotePaused = true;
|
conn.remotePaused = true;
|
||||||
|
|
||||||
conn.once('drain', function () {
|
conn.once('drain', function () {
|
||||||
wsHandlers.sendMessage(Packer.pack(opts, conn.tunnelRead, 'resume'));
|
var packBody = true;
|
||||||
|
wsHandlers.sendMessage(Packer.packHeader(opts, conn.tunnelRead, 'resume', packBody));
|
||||||
conn.remotePaused = false;
|
conn.remotePaused = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -188,7 +198,8 @@ function _connect(state) {
|
|||||||
var cmd = [id, name].concat(Array.prototype.slice.call(arguments, 1));
|
var cmd = [id, name].concat(Array.prototype.slice.call(arguments, 1));
|
||||||
if (state.debug) { console.log('[DEBUG] command sending', cmd); }
|
if (state.debug) { console.log('[DEBUG] command sending', cmd); }
|
||||||
|
|
||||||
wsHandlers.sendMessage(Packer.pack(null, cmd, 'control'));
|
var packBody = true;
|
||||||
|
wsHandlers.sendMessage(Packer.packHeader(null, cmd, 'control', packBody));
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
if (pendingCommands[id]) {
|
if (pendingCommands[id]) {
|
||||||
console.warn('command', name, id, 'timed out');
|
console.warn('command', name, id, 'timed out');
|
||||||
@ -236,6 +247,23 @@ function _connect(state) {
|
|||||||
|
|
||||||
var connCallback;
|
var connCallback;
|
||||||
|
|
||||||
|
function hyperPeek(tun) {
|
||||||
|
var m;
|
||||||
|
var str;
|
||||||
|
if (tun.data) {
|
||||||
|
if ('http' === tun.service) {
|
||||||
|
str = tun.data.toString();
|
||||||
|
m = str.match(/(?:^|[\r\n])Host: ([^\r\n]+)[\r\n]*/im);
|
||||||
|
tun._name = tun._hostname = (m && m[1].toLowerCase() || '').split(':')[0];
|
||||||
|
}
|
||||||
|
else if ('https' === tun.service || 'tls' === tun.service) {
|
||||||
|
tun._name = tun._servername = sni(tun.data);
|
||||||
|
} else {
|
||||||
|
tun._name = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var packerHandlers = {
|
var packerHandlers = {
|
||||||
oncontrol: function (opts) {
|
oncontrol: function (opts) {
|
||||||
var cmd, err;
|
var cmd, err;
|
||||||
@ -294,27 +322,18 @@ function _connect(state) {
|
|||||||
err = { message: 'unknown command "'+cmd[1]+'"', code: 'E_UNKNOWN_COMMAND' };
|
err = { message: 'unknown command "'+cmd[1]+'"', code: 'E_UNKNOWN_COMMAND' };
|
||||||
}
|
}
|
||||||
|
|
||||||
wsHandlers.sendMessage(Packer.pack(null, [-cmd[0], err], 'control'));
|
var packBody = true;
|
||||||
|
wsHandlers.sendMessage(Packer.packHeader(null, [-cmd[0], err], 'control', packBody));
|
||||||
}
|
}
|
||||||
|
|
||||||
, onmessage: function (tun) {
|
, onconnection: function (tun) {
|
||||||
var cid = tun._id = Packer.addrToId(tun);
|
var cid = tun._id = Packer.addrToId(tun);
|
||||||
var str;
|
|
||||||
var m;
|
|
||||||
|
|
||||||
if ('http' === tun.service) {
|
// this data should have been gathered already as part of the proxy protocol
|
||||||
str = tun.data.toString();
|
// but if it's available again here we can double check
|
||||||
m = str.match(/(?:^|[\r\n])Host: ([^\r\n]+)[\r\n]*/im);
|
hyperPeek(tun);
|
||||||
tun._name = tun._hostname = (m && m[1].toLowerCase() || '').split(':')[0];
|
|
||||||
}
|
|
||||||
else if ('https' === tun.service || 'tls' === tun.service) {
|
|
||||||
tun._name = tun._servername = sni(tun.data);
|
|
||||||
} else {
|
|
||||||
tun._name = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clientHandlers.write(cid, tun)) { return; }
|
|
||||||
|
|
||||||
|
// TODO use readable streams instead
|
||||||
wstunneler.pause();
|
wstunneler.pause();
|
||||||
require(state.sortingHat).assign(state, tun, function (err, conn) {
|
require(state.sortingHat).assign(state, tun, function (err, conn) {
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -328,6 +347,18 @@ function _connect(state) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
, onmessage: function (tun) {
|
||||||
|
var cid = tun._id = Packer.addrToId(tun);
|
||||||
|
var handled;
|
||||||
|
|
||||||
|
hyperPeek(tun);
|
||||||
|
|
||||||
|
handled = clientHandlers.write(cid, tun);
|
||||||
|
|
||||||
|
// quasi backwards compat
|
||||||
|
if (!handled) { console.log("[debug] did not get 'connection' event"); packerHandlers.onconnection(tun); }
|
||||||
|
}
|
||||||
|
|
||||||
, onpause: function (opts) {
|
, onpause: function (opts) {
|
||||||
var cid = Packer.addrToId(opts);
|
var cid = Packer.addrToId(opts);
|
||||||
if (localclients[cid]) {
|
if (localclients[cid]) {
|
||||||
@ -338,7 +369,8 @@ function _connect(state) {
|
|||||||
console.log('[TunnelPause] remote tried pausing finished connection', cid);
|
console.log('[TunnelPause] remote tried pausing finished connection', cid);
|
||||||
// Often we have enough latency that we've finished sending before we're told to pause, so
|
// Often we have enough latency that we've finished sending before we're told to pause, so
|
||||||
// don't worry about sending back errors, since we won't be sending data over anyway.
|
// don't worry about sending back errors, since we won't be sending data over anyway.
|
||||||
// wsHandlers.sendMessage(Packer.pack(opts, {message: 'no matching connection', code: 'E_NO_CONN'}, 'error'));
|
// var packBody = true;
|
||||||
|
// wsHandlers.sendMessage(Packer.packHeader(opts, {message: 'no matching connection', code: 'E_NO_CONN'}, 'error', packBody));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
, onresume: function (opts) {
|
, onresume: function (opts) {
|
||||||
@ -349,7 +381,8 @@ function _connect(state) {
|
|||||||
localclients[cid].resume();
|
localclients[cid].resume();
|
||||||
} else {
|
} else {
|
||||||
console.log('[TunnelResume] remote tried resuming finished connection', cid);
|
console.log('[TunnelResume] remote tried resuming finished connection', cid);
|
||||||
// wsHandlers.sendMessage(Packer.pack(opts, {message: 'no matching connection', code: 'E_NO_CONN'}, 'error'));
|
// var packBody = true;
|
||||||
|
// wsHandlers.sendMessage(Packer.packHeader(opts, {message: 'no matching connection', code: 'E_NO_CONN'}, 'error', packBody));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,7 +399,7 @@ function _connect(state) {
|
|||||||
|
|
||||||
, _onConnectError: function (cid, opts, err) {
|
, _onConnectError: function (cid, opts, err) {
|
||||||
console.info("[_onConnectError] opening '" + cid + "' failed because " + err.message);
|
console.info("[_onConnectError] opening '" + cid + "' failed because " + err.message);
|
||||||
wsHandlers.sendMessage(Packer.pack(opts, null, 'error'));
|
wsHandlers.sendMessage(Packer.packHeader(opts, null, 'error'));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -362,21 +362,47 @@ module.exports.assign = function (state, tun, cb) {
|
|||||||
state._serveIndex = require('serve-index');
|
state._serveIndex = require('serve-index');
|
||||||
var serveIndex;
|
var serveIndex;
|
||||||
var serveStatic;
|
var serveStatic;
|
||||||
|
var dlStatic;
|
||||||
if (isFile) {
|
if (isFile) {
|
||||||
serveStatic = state._serveStatic(path.dirname(conf.handler), { dotfiles: 'allow', index: [ 'index.html' ] });
|
serveStatic = state._serveStatic(path.dirname(conf.handler), { dotfiles: 'allow', index: [ 'index.html' ] });
|
||||||
|
dlStatic = state._serveStatic(path.dirname(conf.handler), { acceptRanges: false, dotfiles: 'allow', index: [ 'index.html' ] });
|
||||||
serveIndex = function (req, res, next) { next(); };
|
serveIndex = function (req, res, next) { next(); };
|
||||||
isFile = path.basename(conf.handler);
|
isFile = path.basename(conf.handler);
|
||||||
} else {
|
} else {
|
||||||
serveStatic = state._serveStatic(conf.handler, { dotfiles: 'allow', index: [ 'index.html' ] });
|
serveStatic = state._serveStatic(conf.handler, { dotfiles: 'allow', index: [ 'index.html' ] });
|
||||||
serveIndex = state._serveIndex(conf.handler, { hidden: true, icons: true, view: 'tiles' });
|
dlStatic = state._serveStatic(conf.handler, { acceptRanges: false, dotfiles: 'allow', index: [ 'index.html' ] });
|
||||||
|
serveIndex = state._serveIndex(conf.handler, {
|
||||||
|
hidden: true, icons: true
|
||||||
|
, template: require('serve-tpl-attachment')({ privatefiles: 'ignore' })
|
||||||
|
});
|
||||||
}
|
}
|
||||||
handler = function (req, res) {
|
handler = function (req, res) {
|
||||||
|
var qIndex = req.url.indexOf('?');
|
||||||
|
var fIndex;
|
||||||
|
var fname;
|
||||||
|
if (-1 === qIndex) {
|
||||||
|
qIndex = req.url.length;
|
||||||
|
}
|
||||||
|
req.querystring = req.url.substr(qIndex);
|
||||||
|
req.url = req.url.substr(0, qIndex);
|
||||||
|
req.query = require('querystring').parse(req.querystring.substr(1));
|
||||||
if (isFile) {
|
if (isFile) {
|
||||||
req.url = '/' + isFile;
|
req.url = '/' + isFile;
|
||||||
}
|
}
|
||||||
serveStatic(req, res, function () {
|
//console.log('[req.query]', req.url, req.query);
|
||||||
serveIndex(req, res, state._finalHandler(req, res));
|
if (req.query.download) {
|
||||||
});
|
fIndex = req.url.lastIndexOf('/');
|
||||||
|
fname = req.url.substr(fIndex + 1);
|
||||||
|
res.setHeader('Content-Disposition', 'attachment; filename="'+decodeURIComponent(fname)+'"');
|
||||||
|
res.setHeader('Content-Type', 'application/octet-stream');
|
||||||
|
dlStatic(req, res, function () {
|
||||||
|
serveIndex(req, res, state._finalHandler(req, res));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
serveStatic(req, res, function () {
|
||||||
|
serveIndex(req, res, state._finalHandler(req, res));
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
handlerservers[conf.handler] = http.createServer(handler);
|
handlerservers[conf.handler] = http.createServer(handler);
|
||||||
handlerservers[conf.handler].emit('connection', tlsSocket);
|
handlerservers[conf.handler].emit('connection', tlsSocket);
|
||||||
|
@ -8,6 +8,7 @@ module.exports = function (pkg) {
|
|||||||
https.get(url, function (resp) {
|
https.get(url, function (resp) {
|
||||||
var str = '';
|
var str = '';
|
||||||
resp.on('data', function (chunk) {
|
resp.on('data', function (chunk) {
|
||||||
|
//var chunk = conn.read();
|
||||||
str += chunk.toString('utf8');
|
str += chunk.toString('utf8');
|
||||||
});
|
});
|
||||||
resp.on('end', function () {
|
resp.on('end', function () {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "telebit",
|
"name": "telebit",
|
||||||
"version": "0.19.28",
|
"version": "0.20.0-wip",
|
||||||
"description": "Break out of localhost. Connect to any device from anywhere over any tcp port or securely in a browser. A secure tunnel. A poor man's reverse VPN.",
|
"description": "Break out of localhost. Connect to any device from anywhere over any tcp port or securely in a browser. A secure tunnel. A poor man's reverse VPN.",
|
||||||
"main": "lib/remote.js",
|
"main": "lib/remote.js",
|
||||||
"files": [
|
"files": [
|
||||||
@ -59,15 +59,16 @@
|
|||||||
"js-yaml": "^3.11.0",
|
"js-yaml": "^3.11.0",
|
||||||
"jsonwebtoken": "^7.1.9",
|
"jsonwebtoken": "^7.1.9",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"proxy-packer": "^1.4.3",
|
"proxy-packer": "^2.0.2",
|
||||||
"ps-list": "^5.0.0",
|
"ps-list": "^5.0.0",
|
||||||
"recase": "^1.0.4",
|
"recase": "^1.0.4",
|
||||||
"redirect-https": "^1.1.5",
|
"redirect-https": "^1.1.5",
|
||||||
"serve-index": "^1.9.1",
|
"serve-index": "^1.9.1",
|
||||||
"serve-static": "^1.13.2",
|
"serve-static": "^1.13.2",
|
||||||
|
"serve-tpl-attachment": "^1.0.4",
|
||||||
"sni": "^1.0.0",
|
"sni": "^1.0.0",
|
||||||
"socket-pair": "^1.0.3",
|
"socket-pair": "^1.0.3",
|
||||||
"ws": "^2.2.3"
|
"ws": "^2.3.1"
|
||||||
},
|
},
|
||||||
"trulyOptionalDependencies": {
|
"trulyOptionalDependencies": {
|
||||||
"bluebird": "^3.5.1"
|
"bluebird": "^3.5.1"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user