progress towards telebit
This commit is contained in:
parent
ca2e825fe7
commit
e8c580d115
55
README.md
55
README.md
|
@ -91,16 +91,10 @@ email: 'jon@example.com' # must be valid (for certificate recovery and
|
|||
agree_tos: true # agree to the Telebit, Greenlock, and Let's Encrypt TOSes
|
||||
community_member: true # receive infrequent relevant but non-critical updates
|
||||
telemetry: true # contribute to project telemetric data
|
||||
secret: '' # JWT authorization secret. Generate like so:
|
||||
# node -e "console.log(crypto.randomBytes(16).toString('hex'))"
|
||||
remote_options:
|
||||
https_redirect: false # don't redirect http to https remotely
|
||||
secret: '' # Secret with which to sign Tokens for authorization
|
||||
token: '' # A signed Token for authorization
|
||||
servernames: # servernames that will be forwarded here
|
||||
- example.com
|
||||
local_ports: # ports to forward
|
||||
3000: 'http'
|
||||
8443: 'https'
|
||||
5050: true
|
||||
```
|
||||
|
||||
<!--
|
||||
|
@ -152,8 +146,8 @@ You can **integrate telebit.js into your existing codebase** or use the **standa
|
|||
Telebit CLI
|
||||
-----------
|
||||
|
||||
Installs as `stunnel.js` with the alias `jstunnel`
|
||||
(for those that regularly use `stunnel` but still like commandline completion).
|
||||
Installs Telebit Remote as `telebit`
|
||||
(for those that regularly use `telebit` but still like commandline completion).
|
||||
|
||||
### Install
|
||||
|
||||
|
@ -162,44 +156,44 @@ npm install -g telebit
|
|||
```
|
||||
|
||||
```bash
|
||||
npm install -g 'git+https://git@git.coolaj86.com/coolaj86/tunnel-client.js.git#v1'
|
||||
npm install -g 'https://git.coolaj86.com/coolaj86/telebit.js.git#v1'
|
||||
```
|
||||
|
||||
Or if you want to bow down to the kings of the centralized dictator-net:
|
||||
|
||||
How to use `stunnel.js` with your own instance of `stunneld.js`:
|
||||
How to use Telebit Remote with your own instance of Telebit Relay:
|
||||
|
||||
```bash
|
||||
stunnel.js \
|
||||
telebit \
|
||||
--locals <<external domain name>> \
|
||||
--stunneld wss://<<tunnel domain>>:<<tunnel port>> \
|
||||
--relay wss://<<tunnel domain>>:<<tunnel port>> \
|
||||
--secret <<128-bit hex key>>
|
||||
```
|
||||
|
||||
```bash
|
||||
stunnel.js --locals john.example.com --stunneld wss://tunnel.example.com:443 --secret abc123
|
||||
telebit --locals john.example.com --relay wss://tunnel.example.com:443 --secret abc123
|
||||
```
|
||||
|
||||
```bash
|
||||
stunnel.js \
|
||||
telebit \
|
||||
--locals <<protocol>>:<<external domain name>>:<<local port>> \
|
||||
--stunneld wss://<<tunnel domain>>:<<tunnel port>> \
|
||||
--relay wss://<<tunnel domain>>:<<tunnel port>> \
|
||||
--secret <<128-bit hex key>>
|
||||
```
|
||||
|
||||
```bash
|
||||
stunnel.js \
|
||||
telebit \
|
||||
--locals http:john.example.com:3000,https:john.example.com \
|
||||
--stunneld wss://tunnel.example.com:443 \
|
||||
--relay wss://tunnel.example.com:443 \
|
||||
--secret abc123
|
||||
```
|
||||
|
||||
```
|
||||
--secret the same secret used by stunneld (used for authentication)
|
||||
--secret the same secret used by the Telebit Relay (for authentication)
|
||||
--locals comma separated list of <proto>:<servername>:<port> to which
|
||||
incoming http and https should be forwarded
|
||||
--stunneld the domain or ip address at which you are running stunneld.js
|
||||
-k, --insecure ignore invalid ssl certificates from stunneld
|
||||
--relay the domain or ip address at which you are running Telebit Relay
|
||||
-k, --insecure ignore invalid ssl certificates from relay
|
||||
```
|
||||
|
||||
Node.js Library
|
||||
|
@ -208,10 +202,10 @@ Node.js Library
|
|||
### Example
|
||||
|
||||
```javascript
|
||||
var stunnel = require('stunnel');
|
||||
var Telebit = require('telebit');
|
||||
|
||||
stunnel.connect({
|
||||
stunneld: 'wss://tunnel.example.com'
|
||||
Telebit.connect({
|
||||
relay: 'wss://tunnel.example.com'
|
||||
, token: '...'
|
||||
, locals: [
|
||||
// defaults to sending http to local port 80 and https to local port 443
|
||||
|
@ -251,7 +245,7 @@ local handler and the tunnel handler.
|
|||
You could do a little magic like this:
|
||||
|
||||
```js
|
||||
stunnel.connect({
|
||||
Telebit.connect({
|
||||
// ...
|
||||
, net: {
|
||||
createConnection: function (info, cb) {
|
||||
|
@ -286,6 +280,15 @@ stunnel.connect({
|
|||
});
|
||||
```
|
||||
|
||||
TODO
|
||||
====
|
||||
|
||||
Install for user
|
||||
* https://wiki.archlinux.org/index.php/Systemd/User
|
||||
* https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html
|
||||
* `sudo launchctl load -w ~/Library/LaunchAgents/cloud.telebit.remote`
|
||||
* https://serverfault.com/questions/194832/how-to-start-stop-restart-launchd-services-from-the-command-line
|
||||
|
||||
Browser Library
|
||||
=======
|
||||
|
||||
|
|
203
bin/telebit.js
203
bin/telebit.js
|
@ -4,9 +4,43 @@
|
|||
|
||||
var pkg = require('../package.json');
|
||||
|
||||
var program = require('commander');
|
||||
var url = require('url');
|
||||
var stunnel = require('../wsclient.js');
|
||||
var remote = require('../wsclient.js');
|
||||
|
||||
var argv = process.argv.slice(2);
|
||||
//var Greenlock = require('greenlock');
|
||||
|
||||
var confIndex = argv.indexOf('--config');
|
||||
var confpath;
|
||||
if (-1 === confIndex) {
|
||||
confIndex = argv.indexOf('-c');
|
||||
}
|
||||
confpath = argv[confIndex + 1];
|
||||
|
||||
function help() {
|
||||
console.info('');
|
||||
console.info('Usage:');
|
||||
console.info('');
|
||||
console.info('\ttelebit --config <path>');
|
||||
console.info('');
|
||||
console.info('Example:');
|
||||
console.info('');
|
||||
console.info('\ttelebit --config /etc/telebit/telebit.yml');
|
||||
console.info('');
|
||||
console.info('Config:');
|
||||
console.info('');
|
||||
console.info('\tSee https://git.coolaj86.com/coolaj86/telebit.js');
|
||||
console.info('');
|
||||
console.info('');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (-1 === confIndex || -1 !== argv.indexOf('-h') || -1 !== argv.indexOf('--help')) {
|
||||
help();
|
||||
}
|
||||
if (!confpath || /^--/.test(confpath)) {
|
||||
help();
|
||||
}
|
||||
|
||||
var domainsMap = {};
|
||||
var services = {};
|
||||
|
@ -114,6 +148,78 @@ function collectProxies(val, memo) {
|
|||
return memo;
|
||||
}
|
||||
|
||||
function connectTunnel() {
|
||||
var state = {};
|
||||
var services = { https: {}, http: {}, tcp: {} };
|
||||
state.net = {
|
||||
createConnection: function (info, cb) {
|
||||
// data is the hello packet / first chunk
|
||||
// info = { data, servername, port, host, remoteFamily, remoteAddress, remotePort }
|
||||
var net = require('net');
|
||||
// socket = { write, push, end, events: [ 'readable', 'data', 'error', 'end' ] };
|
||||
var socket = net.createConnection({ port: info.port, host: info.host }, cb);
|
||||
return socket;
|
||||
}
|
||||
};
|
||||
|
||||
// Note: the remote needs to know:
|
||||
// what servernames to forward
|
||||
// what ports to forward
|
||||
// what udp ports to forward
|
||||
// redirect http to https automatically
|
||||
// redirect www to nowww automatically
|
||||
Object.keys(state.config.localPorts).forEach(function (port) {
|
||||
var proto = state.config.localPorts[port];
|
||||
if (!proto) { return; }
|
||||
if ('http' === proto) {
|
||||
state.config.servernames.forEach(function (servername) {
|
||||
services.http[servername] = port;
|
||||
});
|
||||
return;
|
||||
}
|
||||
if ('https' === proto) {
|
||||
state.config.servernames.forEach(function (servername) {
|
||||
services.https[servername] = port;
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (true === proto) { proto = 'tcp'; }
|
||||
if ('tcp' !== proto) { throw new Error("unsupported protocol '" + proto + "'"); }
|
||||
//services[proxy.protocol]['*'] = proxy.port;
|
||||
//services[proxy.protocol][proxy.hostname] = proxy.port;
|
||||
services[proto]['*'] = 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('');
|
||||
|
||||
var tun = remote.connect({
|
||||
relay: state.config.relay
|
||||
, locals: state.config.servernames
|
||||
, services: state.services
|
||||
, net: state.net
|
||||
, insecure: state.config.relay_ignore_invalid_certificates
|
||||
, token: state.config.token
|
||||
});
|
||||
|
||||
function sigHandler() {
|
||||
console.log('SIGINT');
|
||||
|
||||
// We want to handle cleanup properly unless something is broken in our cleanup process
|
||||
// that prevents us from exitting, in which case we want the user to be able to send
|
||||
// the signal again and exit the way it normally would.
|
||||
process.removeListener('SIGINT', sigHandler);
|
||||
tun.end();
|
||||
}
|
||||
process.on('SIGINT', sigHandler);
|
||||
}
|
||||
|
||||
var program = require('commander');
|
||||
program
|
||||
.version(pkg.version)
|
||||
//.command('jsurl <url>')
|
||||
|
@ -134,63 +240,22 @@ program
|
|||
.parse(process.argv)
|
||||
;
|
||||
|
||||
function connectTunnel() {
|
||||
program.net = {
|
||||
createConnection: function (info, cb) {
|
||||
// data is the hello packet / first chunk
|
||||
// info = { data, servername, port, host, remoteFamily, remoteAddress, remotePort }
|
||||
var net = require('net');
|
||||
// socket = { write, push, end, events: [ 'readable', 'data', 'error', 'end' ] };
|
||||
var socket = net.createConnection({ port: info.port, host: info.host }, cb);
|
||||
return socket;
|
||||
}
|
||||
};
|
||||
|
||||
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('');
|
||||
|
||||
var tun = stunnel.connect({
|
||||
stunneld: program.stunneld
|
||||
, locals: program.locals
|
||||
, services: program.services
|
||||
, net: program.net
|
||||
, insecure: program.insecure
|
||||
, token: program.token
|
||||
});
|
||||
|
||||
function sigHandler() {
|
||||
console.log('SIGINT');
|
||||
|
||||
// We want to handle cleanup properly unless something is broken in our cleanup process
|
||||
// that prevents us from exitting, in which case we want the user to be able to send
|
||||
// the signal again and exit the way it normally would.
|
||||
process.removeListener('SIGINT', sigHandler);
|
||||
tun.end();
|
||||
}
|
||||
process.on('SIGINT', sigHandler);
|
||||
}
|
||||
|
||||
function rawTunnel() {
|
||||
program.stunneld = program.stunneld || 'wss://tunnel.daplie.com';
|
||||
program.relay = program.relay || 'wss://telebit.cloud';
|
||||
|
||||
if (!(program.secret || program.token)) {
|
||||
console.error("You must use --secret or --token with --stunneld");
|
||||
console.error("You must use --secret or --token with --relay");
|
||||
process.exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
var location = url.parse(program.stunneld);
|
||||
var location = url.parse(program.relay);
|
||||
if (!location.protocol || /\./.test(location.protocol)) {
|
||||
program.stunneld = 'wss://' + program.stunneld;
|
||||
location = url.parse(program.stunneld);
|
||||
program.relay = 'wss://' + program.relay;
|
||||
location = url.parse(program.relay);
|
||||
}
|
||||
var aud = location.hostname + (location.port ? ':' + location.port : '');
|
||||
program.stunneld = location.protocol + '//' + aud;
|
||||
program.relay = location.protocol + '//' + aud;
|
||||
|
||||
if (!program.token) {
|
||||
var jwt = require('jsonwebtoken');
|
||||
|
@ -205,41 +270,6 @@ function rawTunnel() {
|
|||
connectTunnel();
|
||||
}
|
||||
|
||||
function daplieTunnel() {
|
||||
//var OAUTH3 = require('oauth3.js');
|
||||
var Oauth3Cli = require('oauth3.js/bin/oauth3.js');
|
||||
require('oauth3.js/oauth3.tunnel.js');
|
||||
return Oauth3Cli.login({
|
||||
email: program.email
|
||||
, providerUri: program.oauth3Url || 'oauth3.org'
|
||||
}).then(function (oauth3) {
|
||||
var data = { device: null, domains: [] };
|
||||
var domains = Object.keys(domainsMap).filter(Boolean);
|
||||
if (program.device) {
|
||||
// TODO use device API to select device by id
|
||||
data.device = { hostname: program.device };
|
||||
if (true === program.device) {
|
||||
data.device.hostname = require('os').hostname();
|
||||
console.log("Using device hostname '" + data.device.hostname + "'");
|
||||
}
|
||||
}
|
||||
if (domains.length) {
|
||||
data.domains = domains;
|
||||
}
|
||||
return oauth3.api('tunnel.token', { data: data }).then(function (results) {
|
||||
var token = new Buffer(results.jwt.split('.')[1], 'base64').toString('utf8');
|
||||
console.info('');
|
||||
console.info('tunnel token issued:');
|
||||
console.info(token);
|
||||
console.info('');
|
||||
program.token = results.jwt;
|
||||
program.stunneld = results.tunnelUrl || ('wss://' + token.aud + '/');
|
||||
|
||||
connectTunnel();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
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.
|
||||
|
@ -282,11 +312,6 @@ services.http['*'] = services.http['*'] || services.https['*'];
|
|||
|
||||
program.services = services;
|
||||
|
||||
if (!(program.secret || program.token) && !program.stunneld) {
|
||||
daplieTunnel();
|
||||
}
|
||||
else {
|
||||
rawTunnel();
|
||||
}
|
||||
|
||||
}());
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
# Pre-req
|
||||
# sudo adduser telebit --home /opt/telebit
|
||||
# sudo mkdir -p /opt/telebit/
|
||||
# sudo chown -R telebit:telebit /opt/telebit/
|
||||
|
||||
[Unit]
|
||||
Description=Telebit Relay
|
||||
Documentation=https://git.coolaj86.com/coolaj86/telebit.js/
|
||||
After=network-online.target
|
||||
Wants=network-online.target systemd-networkd-wait-online.service
|
||||
|
||||
[Service]
|
||||
# Restart on crash (bad signal), but not on 'clean' failure (error exit code)
|
||||
# Allow up to 3 restarts within 10 seconds
|
||||
# (it's unlikely that a user or properly-running script will do this)
|
||||
Restart=on-abnormal
|
||||
StartLimitInterval=10
|
||||
StartLimitBurst=3
|
||||
|
||||
# User and group the process will run as
|
||||
# (git is the de facto standard on most systems)
|
||||
User=telebit
|
||||
Group=telebit
|
||||
|
||||
WorkingDirectory=/opt/telebit
|
||||
# custom directory cannot be set and will be the place where gitea exists, not the working directory
|
||||
ExecStart=/opt/telebit/bin/node /opt/telebit/bin/telebit.js --config /etc/telebit/telebit.yml
|
||||
ExecReload=/bin/kill -USR1 $MAINPID
|
||||
|
||||
# Limit the number of file descriptors and processes; see `man systemd.exec` for more limit settings.
|
||||
# Unmodified gitea is not expected to use more than this.
|
||||
LimitNOFILE=1048576
|
||||
LimitNPROC=64
|
||||
|
||||
# Use private /tmp and /var/tmp, which are discarded after gitea stops.
|
||||
PrivateTmp=true
|
||||
# Use a minimal /dev
|
||||
PrivateDevices=true
|
||||
# Hide /home, /root, and /run/user. Nobody will steal your SSH-keys.
|
||||
ProtectHome=true
|
||||
# Make /usr, /boot, /etc and possibly some more folders read-only.
|
||||
ProtectSystem=full
|
||||
# ... except /opt/gitea because we want a place for the database
|
||||
# and /var/log/gitea because we want a place where logs can go.
|
||||
# This merely retains r/w access rights, it does not add any new.
|
||||
# Must still be writable on the host!
|
||||
ReadWriteDirectories=/opt/telebit /etc/telebit
|
||||
|
||||
# Note: in v231 and above ReadWritePaths has been renamed to ReadWriteDirectories
|
||||
; ReadWritePaths=/opt/telebit /etc/telebit
|
||||
|
||||
# The following additional security directives only work with systemd v229 or later.
|
||||
# They further retrict privileges that can be gained by gitea.
|
||||
# Note that you may have to add capabilities required by any plugins in use.
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
NoNewPrivileges=true
|
||||
|
||||
# Caveat: Some features may need additional capabilities.
|
||||
# For example an "upload" may need CAP_LEASE
|
||||
; CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_LEASE
|
||||
; AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_LEASE
|
||||
; NoNewPrivileges=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -0,0 +1,16 @@
|
|||
email: 'jon@example.com' # must be valid (for certificate recovery and security alerts)
|
||||
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
|
||||
relay: wss://telebit.cloud # Which Telebit Relay to use
|
||||
secret: '' # Token or Secret to use for authorization
|
||||
token: '' # Token or Secret to use for authorization
|
||||
remote_options:
|
||||
https_redirect: true # redirect http to https remotely (default)
|
||||
servernames: # hostnames that direct to the Telebit Relay admin console
|
||||
- example.com
|
||||
- example.net
|
||||
local_ports: # ports to forward
|
||||
3000: 'http'
|
||||
8443: 'https'
|
||||
5050: true
|
|
@ -0,0 +1,8 @@
|
|||
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
|
||||
remote_options:
|
||||
https_redirect: true # redirect http to https remotely (default)
|
||||
local_ports: # ports to forward
|
||||
3001: 'http'
|
||||
9443: 'https'
|
|
@ -0,0 +1,249 @@
|
|||
#!/bin/bash
|
||||
#<pre><code>
|
||||
|
||||
# This is a 3 step process
|
||||
# 1. First we need to figure out whether to use wget or curl for fetching remote files
|
||||
# 2. Next we need to figure out whether to use unzip or tar for downloading releases
|
||||
# 3. We need to actually install the stuff
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
###############################
|
||||
# #
|
||||
# http_get #
|
||||
# boilerplate for curl / wget #
|
||||
# #
|
||||
###############################
|
||||
|
||||
# See https://git.coolaj86.com/coolaj86/snippets/blob/master/bash/http-get.sh
|
||||
|
||||
_my_http_get=""
|
||||
_my_http_opts=""
|
||||
_my_http_out=""
|
||||
|
||||
detect_http_get()
|
||||
{
|
||||
set +e
|
||||
if type -p curl >/dev/null 2>&1; then
|
||||
_my_http_get="curl"
|
||||
_my_http_opts="-fsSL"
|
||||
_my_http_out="-o"
|
||||
elif type -p wget >/dev/null 2>&1; then
|
||||
_my_http_get="wget"
|
||||
_my_http_opts="--quiet"
|
||||
_my_http_out="-O"
|
||||
else
|
||||
echo "Aborted, could not find curl or wget"
|
||||
return 7
|
||||
fi
|
||||
set -e
|
||||
}
|
||||
|
||||
http_get()
|
||||
{
|
||||
$_my_http_get $_my_http_opts $_my_http_out "$2" "$1"
|
||||
touch "$2"
|
||||
}
|
||||
|
||||
http_bash()
|
||||
{
|
||||
_http_url=$1
|
||||
my_args=${2:-}
|
||||
rm -rf my-tmp-runner.sh
|
||||
$_my_http_get $_my_http_opts $_my_http_out my-tmp-runner.sh "$_http_url"; bash my-tmp-runner.sh $my_args; rm my-tmp-runner.sh
|
||||
}
|
||||
|
||||
detect_http_get
|
||||
|
||||
###############################
|
||||
## END HTTP_GET ##
|
||||
###############################
|
||||
|
||||
my_email=${1:-}
|
||||
my_relay=${2:-}
|
||||
my_servernames=${3:-}
|
||||
my_secret=${4:-}
|
||||
my_user="telebit"
|
||||
my_app="telebit"
|
||||
my_bin="telebit.js"
|
||||
my_name="Telebit Remote"
|
||||
my_repo="telebit.js"
|
||||
|
||||
if [ -z "${my_email}" ]; then
|
||||
echo ""
|
||||
echo ""
|
||||
echo "Telebit uses Greenlock for free automated ssl through Let's Encrypt."
|
||||
echo ""
|
||||
echo "To accept the Terms of Service for Telebit, Greenlock and Let's Encrypt,"
|
||||
echo "please enter your email."
|
||||
echo ""
|
||||
read -p "email: " my_email
|
||||
echo ""
|
||||
# UX - just want a smooth transition
|
||||
sleep 0.5
|
||||
fi
|
||||
|
||||
if [ -z "${my_relay}" ]; then
|
||||
echo "What relay will you be using?"
|
||||
echo ""
|
||||
read -p "relay (ex: wss://telebit.cloud): " my_relay
|
||||
echo ""
|
||||
# UX - just want a smooth transition
|
||||
sleep 0.5
|
||||
fi
|
||||
|
||||
if [ -z "${my_servernames}" ]; then
|
||||
echo "What servername(s) will you be relaying here?"
|
||||
echo ""
|
||||
read -p "domain (ex: example.com,example.net): " my_servernames
|
||||
echo ""
|
||||
# UX - just want a smooth transition
|
||||
sleep 0.5
|
||||
fi
|
||||
|
||||
if [ -z "${my_secret}" ]; then
|
||||
echo "What's your authorization for the relay server?"
|
||||
echo ""
|
||||
read -p "auth: " my_secret
|
||||
echo ""
|
||||
# UX - just want a smooth transition
|
||||
sleep 0.5
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
if [ -z "${TELEBIT_PATH:-}" ]; then
|
||||
echo 'TELEBIT_PATH="'${TELEBIT_PATH:-}'"'
|
||||
TELEBIT_PATH=/opt/$my_app
|
||||
fi
|
||||
|
||||
echo "Installing $my_name to '$TELEBIT_PATH'"
|
||||
|
||||
echo "Installing node.js dependencies into $TELEBIT_PATH"
|
||||
# v10.2+ has much needed networking fixes, but breaks ursa. v9.x has severe networking bugs. v8.x has working ursa, but requires tls workarounds"
|
||||
NODEJS_VER="${NODEJS_VER:-v10}"
|
||||
export NODEJS_VER
|
||||
export NODE_PATH="$TELEBIT_PATH/lib/node_modules"
|
||||
export NPM_CONFIG_PREFIX="$TELEBIT_PATH"
|
||||
export PATH="$TELEBIT_PATH/bin:$PATH"
|
||||
sleep 1
|
||||
http_bash https://git.coolaj86.com/coolaj86/node-installer.sh/raw/branch/master/install.sh --no-dev-deps >/dev/null 2>/dev/null
|
||||
|
||||
my_tree="master"
|
||||
my_node="$TELEBIT_PATH/bin/node"
|
||||
my_secret=$($my_node -e "console.info(crypto.randomBytes(16).toString('hex'))")
|
||||
my_npm="$my_node $TELEBIT_PATH/bin/npm"
|
||||
my_tmp="$TELEBIT_PATH/tmp"
|
||||
mkdir -p $my_tmp
|
||||
|
||||
echo "sudo mkdir -p '$TELEBIT_PATH'"
|
||||
sudo mkdir -p "$TELEBIT_PATH"
|
||||
echo "sudo mkdir -p '/etc/$my_user/'"
|
||||
sudo mkdir -p "/etc/$my_user/"
|
||||
|
||||
set +e
|
||||
#https://git.coolaj86.com/coolaj86/telebit.js.git
|
||||
#https://git.coolaj86.com/coolaj86/telebit.js/archive/:tree:.tar.gz
|
||||
#https://git.coolaj86.com/coolaj86/telebit.js/archive/:tree:.zip
|
||||
my_unzip=$(type -p unzip)
|
||||
my_tar=$(type -p tar)
|
||||
if [ -n "$my_unzip" ]; then
|
||||
rm -f $my_tmp/$my_app-$my_tree.zip
|
||||
http_get https://git.coolaj86.com/coolaj86/$my_repo/archive/$my_tree.zip $my_tmp/$my_app-$my_tree.zip
|
||||
# -o means overwrite, and there is no option to strip
|
||||
$my_unzip -o $my_tmp/$my_app-$my_tree.zip -d $TELEBIT_PATH/ > /dev/null 2>&1
|
||||
cp -ar $TELEBIT_PATH/$my_repo/* $TELEBIT_PATH/ > /dev/null
|
||||
rm -rf $TELEBIT_PATH/$my_bin
|
||||
elif [ -n "$my_tar" ]; then
|
||||
rm -f $my_tmp/$my_app-$my_tree.tar.gz
|
||||
http_get https://git.coolaj86.com/coolaj86/$my_repo/archive/$my_tree.tar.gz $my_tmp/$my_app-$my_tree.tar.gz
|
||||
ls -lah $my_tmp/$my_app-$my_tree.tar.gz
|
||||
$my_tar -xzf $my_tmp/$my_app-$my_tree.tar.gz --strip 1 -C $TELEBIT_PATH/
|
||||
else
|
||||
echo "Neither tar nor unzip found. Abort."
|
||||
exit 13
|
||||
fi
|
||||
set -e
|
||||
|
||||
pushd $TELEBIT_PATH >/dev/null
|
||||
$my_npm install >/dev/null 2>/dev/null
|
||||
popd >/dev/null
|
||||
|
||||
cat << EOF > $TELEBIT_PATH/bin/$my_app
|
||||
#!/bin/bash
|
||||
$my_node $TELEBIT_PATH/bin/$my_bin
|
||||
EOF
|
||||
chmod a+x $TELEBIT_PATH/bin/$my_app
|
||||
echo "sudo ln -sf $TELEBIT_PATH/bin/$my_app /usr/local/bin/$my_app"
|
||||
sudo ln -sf $TELEBIT_PATH/bin/$my_app /usr/local/bin/$my_app
|
||||
|
||||
set +e
|
||||
if type -p setcap >/dev/null 2>&1; then
|
||||
#echo "Setting permissions to allow $my_app to run on port 80 and port 443 without sudo or root"
|
||||
echo "sudo setcap cap_net_bind_service=+ep $TELEBIT_PATH/bin/node"
|
||||
sudo setcap cap_net_bind_service=+ep $TELEBIT_PATH/bin/node
|
||||
fi
|
||||
set -e
|
||||
|
||||
if [ -z "$(cat /etc/passwd | grep $my_user)" ]; then
|
||||
echo "sudo adduser --home $TELEBIT_PATH --gecos '' --disabled-password $my_user"
|
||||
sudo adduser --home $TELEBIT_PATH --gecos '' --disabled-password $my_user >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
if [ ! -f "/etc/$my_user/$my_app.yml" ]; then
|
||||
echo "### Creating config file from template. sudo may be required"
|
||||
#echo "sudo rsync -a examples/$my_app.yml /etc/$my_user/$my_app.yml"
|
||||
sudo bash -c "echo 'email: $my_email' >> /etc/$my_user/$my_app.yml"
|
||||
sudo bash -c "echo 'secret: $my_secret' >> /etc/$my_user/$my_app.yml"
|
||||
sudo bash -c "echo 'servernames: [ $my_servernames ]' >> /etc/$my_user/$my_app.yml"
|
||||
sudo bash -c "cat examples/$my_app.yml.tpl >> /etc/$my_user/$my_app.yml"
|
||||
fi
|
||||
|
||||
echo "sudo chown -R $my_user '$TELEBIT_PATH' '/etc/$my_user'"
|
||||
sudo chown -R $my_user "$TELEBIT_PATH" "/etc/$my_user"
|
||||
|
||||
echo "### Adding $my_app is a system service"
|
||||
echo "sudo rsync -a $TELEBIT_PATH/dist/etc/systemd/system/$my_app.service /etc/systemd/system/$my_app.service"
|
||||
sudo rsync -a $TELEBIT_PATH/dist/etc/systemd/system/$my_app.service /etc/systemd/system/$my_app.service
|
||||
sudo systemctl daemon-reload
|
||||
echo "sudo systemctl enable $my_app"
|
||||
sudo systemctl enable $my_app
|
||||
echo "sudo systemctl start $my_app"
|
||||
sudo systemctl restart $my_app
|
||||
|
||||
sleep 1
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
echo "=============================================="
|
||||
echo " Privacy Settings in Config"
|
||||
echo "=============================================="
|
||||
echo ""
|
||||
echo "The example config file /etc/$my_user/$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."
|
||||
echo ""
|
||||
echo "Please edit the config file to meet your needs before starting."
|
||||
echo ""
|
||||
sleep 2
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo "=============================================="
|
||||
echo "Installed successfully. Last steps:"
|
||||
echo "=============================================="
|
||||
echo ""
|
||||
echo "Edit the config and restart, if desired:"
|
||||
echo ""
|
||||
echo " sudo vim /etc/$my_user/$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 /etc/$my_user/$my_app.yml"
|
||||
echo ""
|
||||
sleep 1
|
|
@ -415,7 +415,7 @@ function run(copts) {
|
|||
}
|
||||
|
||||
, onOpen: function () {
|
||||
console.info("[open] connected to '" + copts.stunneld + "'");
|
||||
console.info("[open] connected to '" + copts.relay + "'");
|
||||
wsHandlers.refreshTimeout();
|
||||
timeoutId = setTimeout(wsHandlers.checkTimeout, activityTimeout);
|
||||
|
||||
|
@ -500,8 +500,8 @@ function run(copts) {
|
|||
timeoutId = null;
|
||||
var machine = require('tunnel-packer').create(packerHandlers);
|
||||
|
||||
console.info("[connect] '" + copts.stunneld + "'");
|
||||
var tunnelUrl = copts.stunneld.replace(/\/$/, '') + '/?access_token=' + tokens[0];
|
||||
console.info("[connect] '" + copts.relay + "'");
|
||||
var tunnelUrl = copts.relay.replace(/\/$/, '') + '/?access_token=' + tokens[0];
|
||||
wstunneler = new WebSocket(tunnelUrl, { rejectUnauthorized: !copts.insecure });
|
||||
wstunneler.on('open', wsHandlers.onOpen);
|
||||
wstunneler.on('close', wsHandlers.onClose);
|
||||
|
|
Loading…
Reference in New Issue