Compare commits

..

No commits in common. "bb018c538dbb3a492fbe5796e3a8d15e52294b6d" and "d700b514941a69291e86d1d644a22859ae27fc71" have entirely different histories.

11 changed files with 538 additions and 645 deletions

6
.gitignore vendored
View File

@ -1,10 +1,4 @@
node_modules.*
include
bin/node
bin/npm
bin/npx
share
etc
# Logs
logs

View File

@ -63,41 +63,6 @@ Windows & Node.js
There is [a bug](https://github.com/nodejs/node/issues/20241) in node v9.x that causes telebit-relay to crash.
Manually Install
-----------
```bash
git clone https://git.coolaj86.com/coolaj86/telebit-relay.js.git telebit-relay
# we're very picky to due to bugs in various versions of v8, v9, and v10
export NODEJS_VER="v10.2.1"
# We can keep everything self-contained
export NPM_CONFIG_PREFIX=/opt/telebit-relay
export NODE_PATH=/opt/telebit-relay/lib/node_modules
curl -fsSL https://bit.ly/node-installer | bash -s -- --no-dev-deps
pushd /opt/telebit-relay
bin/node bin/npm install
rsync -a examples/telebit-relay.yml etc/telebit-relay.yml
rsync -a dist/etc/systemd/system/telebit-relay.service /etc/systemd/system/telebit-relay.service
popd
# IMPORTANT: Season the config file to taste
# IMPORTANT: change your email address and domain
edit /opt/telebit-relay/etc/telebit-relay.yml
adduser --home /opt/telebit-relay --gecos '' --disabled-password telebit >/dev/null 2>&1
sudo chown -R telebit:telebit /opt/telebit-relay/
systemctl daemon-reload
systemctl restart telebit-relay
systemctl status telebit-relay
journalctl -xefu telebit-relay
```
Usage
====

View File

@ -1,7 +0,0 @@
{ "terms_of_service": ":hostname/tos/"
, "api_host": ":hostname"
, "tunnel": {
"method": "wss"
, "pathname": ""
}
}

View File

@ -134,7 +134,7 @@ function applyConfig(config) {
// TODO specify extensions in config file
state.extensions = require('../lib/extensions');
} catch(e) {
if ('ENOENT' !== e.code || state.debug) { console.log('[DEBUG] no extensions loaded', e); }
if (state.debug) { console.log('[DEBUG] no extensions loaded', e); }
state.extensions = {};
}
require('../lib/handlers').create(state); // adds directly to config for now...

View File

@ -2,8 +2,6 @@ email: 'jon@example.com' # must be valid (for certificate recovery and sec
agree_tos: true # agree to the Telebit, Greenlock, and Let's Encrypt TOSes
community_member: true # receive infrequent relevant updates
telemetry: true # contribute to project telemetric data
webmin_domain: example.com
shared_domain: xm.pl
servernames: # hostnames that direct to the Telebit Relay admin console
- telebit.example.com
- telebit.example.net

View File

@ -68,7 +68,6 @@ my_app="telebit-relay"
my_bin="telebit-relay.js"
my_name="Telebit Relay"
my_repo="telebit-relay.js"
exec 3<>/dev/tty
if [ -z "${my_email}" ]; then
echo ""
@ -78,7 +77,7 @@ if [ -z "${my_email}" ]; then
echo "To accept the Terms of Service for Telebit, Greenlock and Let's Encrypt,"
echo "please enter your email."
echo ""
read -u 3 -p "email: " my_email
read -p "email: " my_email
echo ""
# UX - just want a smooth transition
sleep 0.5
@ -87,7 +86,7 @@ fi
if [ -z "${my_servername}" ]; then
echo "What is the domain of this server (for admin interface)?"
echo ""
read -u 3 -p "domain (ex: telebit-relay.example.com): " my_servername
read -p "domain (ex: telebit-relay.example.com): " my_servername
echo ""
# UX - just want a smooth transition
sleep 0.5
@ -121,8 +120,8 @@ mkdir -p $my_tmp
echo "sudo mkdir -p '$TELEBIT_RELAY_PATH'"
sudo mkdir -p "$TELEBIT_RELAY_PATH"
echo "sudo mkdir -p '$TELEBIT_RELAY_PATH/etc'"
sudo mkdir -p "$TELEBIT_RELAY_PATH/etc/"
echo "sudo mkdir -p '/opt/$my_app/etc'"
sudo mkdir -p "/opt/$my_app/etc/"
set +e
#https://git.coolaj86.com/coolaj86/telebit-relay.js.git
@ -173,17 +172,17 @@ if [ -z "$(cat /etc/passwd | grep $my_user)" ]; then
sudo adduser --home $TELEBIT_RELAY_PATH --gecos '' --disabled-password $my_user >/dev/null 2>&1
fi
if [ ! -f "$TELEBIT_RELAY_PATH/etc/$my_app.yml" ]; then
if [ ! -f "/opt/$my_app/etc/$my_app.yml" ]; then
echo "### Creating config file from template. sudo may be required"
#echo "sudo rsync -a examples/$my_app.yml $TELEBIT_RELAY_PATH/etc/$my_app.yml"
sudo bash -c "echo 'email: $my_email' >> $TELEBIT_RELAY_PATH/etc/$my_app.yml"
sudo bash -c "echo 'secret: $my_secret' >> $TELEBIT_RELAY_PATH/etc/$my_app.yml"
sudo bash -c "echo 'servernames: [ $my_servername ]' >> $TELEBIT_RELAY_PATH/etc/$my_app.yml"
sudo bash -c "cat $TELEBIT_RELAY_PATH/examples/$my_app.yml.tpl >> $TELEBIT_RELAY_PATH/etc/$my_app.yml"
#echo "sudo rsync -a examples/$my_app.yml /opt/$my_app/etc/$my_app.yml"
sudo bash -c "echo 'email: $my_email' >> /opt/$my_app/etc/$my_app.yml"
sudo bash -c "echo 'secret: $my_secret' >> /opt/$my_app/etc/$my_app.yml"
sudo bash -c "echo 'servernames: [ $my_servername ]' >> /opt/$my_app/etc/$my_app.yml"
sudo bash -c "cat examples/$my_app.yml.tpl >> /opt/$my_app/etc/$my_app.yml"
fi
echo "sudo chown -R $my_user '$TELEBIT_RELAY_PATH'"
sudo chown -R $my_user "$TELEBIT_RELAY_PATH"
echo "sudo chown -R $my_user '$TELEBIT_RELAY_PATH' '/opt/$my_app/etc'"
sudo chown -R $my_user "$TELEBIT_RELAY_PATH" "/opt/$my_app/etc"
echo "### Adding $my_app is a system service"
echo "sudo rsync -a $TELEBIT_RELAY_PATH/dist/etc/systemd/system/$my_app.service /etc/systemd/system/$my_app.service"
@ -202,7 +201,7 @@ echo "=============================================="
echo " Privacy Settings in Config"
echo "=============================================="
echo ""
echo "The example config file $TELEBIT_RELAY_PATH/etc/$my_app.yml opts-in to"
echo "The example config file /opt/$my_app/etc/$my_app.yml opts-in to"
echo "contributing telemetrics and receiving infrequent relevant updates"
echo "(probably once per quarter or less) such as important notes on"
echo "a new release, an important API change, etc. No spam."
@ -219,13 +218,13 @@ echo "=============================================="
echo ""
echo "Edit the config and restart, if desired:"
echo ""
echo " sudo vim $TELEBIT_RELAY_PATH/etc/$my_app.yml"
echo " sudo vim /opt/$my_app/etc/$my_app.yml"
echo " sudo systemctl restart $my_app"
echo ""
echo "Or disabled the service and start manually:"
echo ""
echo " sudo systemctl stop $my_app"
echo " sudo systemctl disable $my_app"
echo " $my_app --config $TELEBIT_RELAY_PATH/etc/$my_app.yml"
echo " $my_app --config /opt/$my_app/etc/$my_app.yml"
echo ""
sleep 1

View File

@ -52,7 +52,7 @@ module.exports.create = function (state) {
|| redirectHttpsAndClose
);
state.handleInsecureHttp = function (servername, socket) {
console.log("[handlers] insecure http for '" + servername + "'");
console.log("handleInsecureHttp('" + servername + "', socket)");
socket.__my_servername = servername;
state.httpInsecureServer.emit('connection', socket);
};

View File

@ -2,55 +2,42 @@
var Packer = require('proxy-packer');
module.exports = function pipeWs(servername, service, srv, conn, serviceport) {
module.exports = function pipeWs(servername, service, conn, remote, serviceport) {
var browserAddr = Packer.socketToAddr(conn);
var cid = Packer.addrToId(browserAddr);
browserAddr.service = service;
browserAddr.serviceport = serviceport;
browserAddr.name = servername;
conn.tunnelCid = cid;
var rid = Packer.socketToId(srv.upgradeReq.socket);
var rid = Packer.socketToId(remote.upgradeReq.socket);
//if (state.debug) { console.log('[pipeWs] client', cid, '=> remote', rid, 'for', servername, 'via', service); }
function sendWs(data, serviceOverride) {
if (srv.ws && (!conn.tunnelClosing || serviceOverride)) {
if (remote.ws && (!conn.tunnelClosing || serviceOverride)) {
try {
if (data && !Buffer.isBuffer(data)) {
data = Buffer.from(JSON.stringify(data));
}
srv.ws.send(Packer.packHeader(browserAddr, data, serviceOverride), { binary: true });
if (data) {
srv.ws.send(data, { binary: true });
}
remote.ws.send(Packer.pack(browserAddr, data, serviceOverride), { binary: true });
// If we can't send data over the websocket as fast as this connection can send it to us
// (or there are a lot of connections trying to send over the same websocket) then we
// need to pause the connection for a little. We pause all connections if any are paused
// to make things more fair so a connection doesn't get stuck waiting for everyone else
// to finish because it got caught on the boundary. Also if serviceOverride is set it
// means the connection is over, so no need to pause it.
if (!serviceOverride && (srv.pausedConns.length || srv.ws.bufferedAmount > 1024*1024)) {
if (!serviceOverride && (remote.pausedConns.length || remote.ws.bufferedAmount > 1024*1024)) {
// console.log('pausing', cid, 'to allow web socket to catch up');
conn.pause();
srv.pausedConns.push(conn);
remote.pausedConns.push(conn);
}
} catch (err) {
console.warn('[pipeWs] srv', rid, ' => client', cid, 'error sending websocket message', err);
console.warn('[pipeWs] remote', rid, ' => client', cid, 'error sending websocket message', err);
}
}
}
srv.clients[cid] = conn;
conn.servername = servername;
conn.serviceport = serviceport;
conn.service = service;
remote.clients[cid] = conn;
// send peek at data too?
srv.ws.send(Packer.packHeader(browserAddr, null, 'connection'), { binary: true });
// TODO convert to read stream?
conn.on('data', function (chunk) {
//if (state.debug) { console.log('[pipeWs] client', cid, ' => srv', rid, chunk.byteLength, 'bytes'); }
//if (state.debug) { console.log('[pipeWs] client', cid, ' => remote', rid, chunk.byteLength, 'bytes'); }
sendWs(chunk);
});
@ -61,7 +48,7 @@ module.exports = function pipeWs(servername, service, srv, conn, serviceport) {
conn.on('close', function (hadErr) {
//if (state.debug) { console.log('[pipeWs] client', cid, 'closing'); }
sendWs(null, hadErr ? 'error': 'end');
delete srv.clients[cid];
delete remote.clients[cid];
});
};

File diff suppressed because it is too large Load Diff

View File

@ -19,11 +19,6 @@ module.exports.createTcpConnectionHandler = function (state) {
//return;
conn.once('data', function (firstChunk) {
var service = 'tcp';
var servername;
var str;
var m;
conn.pause();
conn.unshift(firstChunk);
@ -36,13 +31,18 @@ module.exports.createTcpConnectionHandler = function (state) {
// defer after return (instead of being in many places)
function deferData(fn) {
if (fn) {
state[fn](servername, conn);
state[fn](servername, conn)
}
process.nextTick(function () {
conn.resume();
});
}
var service = 'tcp';
var servername;
var str;
var m;
function tryTls() {
var vhost;
@ -76,9 +76,9 @@ module.exports.createTcpConnectionHandler = function (state) {
return;
}
if (state.debug) { console.log("pipeWs(servername, service, deviceLists['" + servername + "'], socket)"); }
if (state.debug) { console.log("pipeWs(servername, service, socket, deviceLists['" + servername + "'])"); }
deferData();
pipeWs(servername, service, nextDevice, conn, serviceport);
pipeWs(servername, service, conn, nextDevice, serviceport);
}
// TODO don't run an fs check if we already know this is working elsewhere
@ -86,11 +86,11 @@ module.exports.createTcpConnectionHandler = function (state) {
if (state.config.vhost) {
vhost = state.config.vhost.replace(/:hostname/, (servername||'reallydoesntexist'));
if (state.debug) { console.log("[tcp] [vhost]", state.config.vhost, "=>", vhost); }
//state.httpsVhost(servername, conn);
//state.httpsVhost(servername, conn);
//return;
require('fs').readdir(vhost, function (err, nodes) {
if (state.debug && err) { console.log("VHOST error", err); }
if (err || !nodes) { run(); return; }
if (err) { run(); return; }
//if (nodes) { deferData('httpsVhost'); return; }
deferData('httpsVhost');
});
@ -131,7 +131,7 @@ module.exports.createTcpConnectionHandler = function (state) {
// HTTP
if (Devices.exist(state.deviceLists, servername)) {
deferData();
pipeWs(servername, service, Devices.next(state.deviceLists, servername), conn, serviceport);
pipeWs(servername, service, conn, Devices.next(state.deviceLists, servername), serviceport);
return;
}
deferData('handleHttp');

View File

@ -1,6 +1,6 @@
{
"name": "telebit-relay",
"version": "0.20.0",
"version": "0.12.1",
"description": "Friends don't let friends localhost. Expose your bits with a secure connection even from behind NAT, Firewalls, in a box, with a fox, on a train or in a plane... or a Raspberry Pi in your closet. An attempt to create a better localtunnel.me server, a more open ngrok. Uses Automated HTTPS (Free SSL) via ServerName Indication (SNI). Can also tunnel tls and plain tcp.",
"main": "lib/relay.js",
"bin": {
@ -43,15 +43,15 @@
"greenlock": "^2.2.4",
"human-readable-ids": "^1.0.4",
"js-yaml": "^3.11.0",
"jsonwebtoken": "^8.3.0",
"proxy-packer": "^2.0.0",
"jsonwebtoken": "^8.2.1",
"proxy-packer": "^1.4.3",
"recase": "^1.0.4",
"redirect-https": "^1.1.5",
"serve-static": "^1.13.2",
"sni": "^1.0.0",
"ws": "^5.1.1"
},
"engineStrict": true,
"engineStrict" : true,
"engines": {
"node": "10.2.1"
}