2018-05-15 07:42:43 +00:00
|
|
|
# Telebit™
|
2016-09-30 16:33:38 +00:00
|
|
|
|
2018-02-15 06:27:15 +00:00
|
|
|
A client that works in combination with [stunneld.js](https://git.coolaj86.com/coolaj86/tunnel-server.js)
|
2016-09-30 22:07:26 +00:00
|
|
|
to allow you to serve http and https from any computer, anywhere through a secure tunnel.
|
2016-09-30 16:33:38 +00:00
|
|
|
|
2018-05-15 07:50:37 +00:00
|
|
|
| Sponsored by [ppl](https://ppl.family) | [Telebit Relay](https://git.coolaj86.com/coolaj86/telebitd.js) | **Telebit** |
|
|
|
|
|
2016-10-06 21:01:58 +00:00
|
|
|
* CLI
|
|
|
|
* Library
|
|
|
|
|
2016-09-30 16:33:38 +00:00
|
|
|
CLI
|
|
|
|
===
|
|
|
|
|
|
|
|
Installs as `stunnel.js` with the alias `jstunnel`
|
|
|
|
(for those that regularly use `stunnel` but still like commandline completion).
|
|
|
|
|
|
|
|
### Install
|
|
|
|
|
2017-04-05 22:36:01 +00:00
|
|
|
```bash
|
2018-02-15 06:27:15 +00:00
|
|
|
npm install -g 'git+https://git@git.coolaj86.com/coolaj86/tunnel-client.js.git#v1'
|
2017-04-05 22:36:01 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
Or if you want to bow down to the kings of the centralized dictator-net:
|
|
|
|
|
2016-09-30 16:33:38 +00:00
|
|
|
```bash
|
|
|
|
npm install -g stunnel
|
|
|
|
```
|
|
|
|
|
2017-03-28 21:31:45 +00:00
|
|
|
### Usage with OAuth3.org
|
|
|
|
|
2018-02-15 06:27:15 +00:00
|
|
|
The OAuth3.org tunnel service is in Beta.
|
2017-03-28 21:31:45 +00:00
|
|
|
|
|
|
|
**Terms of Service**: The Software and Services shall be used for Good, not Evil.
|
|
|
|
Examples of good: education, business, pleasure. Examples of evil: crime, abuse, extortion.
|
|
|
|
|
|
|
|
```bash
|
|
|
|
stunnel.js --agree-tos --email john@example.com --locals http:*:4080,https:*:8443 --device
|
|
|
|
```
|
|
|
|
|
|
|
|
```bash
|
|
|
|
stunnel.js \
|
|
|
|
--agree-tos --email <EMAIL> \
|
|
|
|
--locals <List of <SCHEME>:<EXTERNAL_DOMAINNAME>:<INTERNAL_PORT>> \
|
|
|
|
--device [HOSTNAME] \
|
|
|
|
--domains [Comma-separated list of domains to attach to device] \
|
|
|
|
--oauth3-url <Tunnel Service OAuth3 URL>
|
|
|
|
```
|
|
|
|
|
|
|
|
### Advanced Usage (DIY)
|
2016-09-30 16:33:38 +00:00
|
|
|
|
|
|
|
How to use `stunnel.js` with your own instance of `stunneld.js`:
|
|
|
|
|
2017-03-26 07:37:26 +00:00
|
|
|
```bash
|
|
|
|
stunnel.js \
|
|
|
|
--locals <<external domain name>> \
|
|
|
|
--stunneld wss://<<tunnel domain>>:<<tunnel port>> \
|
|
|
|
--secret <<128-bit hex key>>
|
|
|
|
```
|
|
|
|
|
2016-09-30 16:33:38 +00:00
|
|
|
```bash
|
2016-10-06 21:16:21 +00:00
|
|
|
stunnel.js --locals john.example.com --stunneld wss://tunnel.example.com:443 --secret abc123
|
|
|
|
```
|
|
|
|
|
2017-03-26 07:37:26 +00:00
|
|
|
```bash
|
|
|
|
stunnel.js \
|
|
|
|
--locals <<protocol>>:<<external domain name>>:<<local port>> \
|
|
|
|
--stunneld wss://<<tunnel domain>>:<<tunnel port>> \
|
|
|
|
--secret <<128-bit hex key>>
|
|
|
|
```
|
|
|
|
|
2016-10-06 21:16:21 +00:00
|
|
|
```bash
|
|
|
|
stunnel.js \
|
|
|
|
--locals http:john.example.com:3000,https:john.example.com \
|
|
|
|
--stunneld wss://tunnel.example.com:443 \
|
|
|
|
--secret abc123
|
2016-09-30 16:33:38 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
```
|
|
|
|
--secret the same secret used by stunneld (used 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
|
|
|
|
```
|
|
|
|
|
2016-10-06 21:01:58 +00:00
|
|
|
Library
|
|
|
|
=======
|
|
|
|
|
|
|
|
### Example
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
var stunnel = require('stunnel');
|
|
|
|
|
|
|
|
stunnel.connect({
|
|
|
|
stunneld: 'wss://tunnel.example.com'
|
|
|
|
, token: '...'
|
|
|
|
, locals: [
|
|
|
|
// defaults to sending http to local port 80 and https to local port 443
|
|
|
|
{ hostname: 'doe.net' }
|
|
|
|
|
|
|
|
// sends both http and https to local port 3000 (httpolyglot)
|
|
|
|
, { protocol: 'https', hostname: 'john.doe.net', port: 3000 }
|
|
|
|
|
|
|
|
// send http to local port 4080 and https to local port 8443
|
|
|
|
, { protocol: 'https', hostname: 'jane.doe.net', port: 4080 }
|
|
|
|
, { protocol: 'https', hostname: 'jane.doe.net', port: 8443 }
|
|
|
|
]
|
|
|
|
|
|
|
|
, net: require('net')
|
|
|
|
, insecure: false
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
2016-10-11 21:39:06 +00:00
|
|
|
* You can get sneaky with `net` and provide a `createConnection` that returns a `stream.Duplex`.
|
2016-10-06 21:01:58 +00:00
|
|
|
|
|
|
|
### Token
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
var tokenData = { domains: [ 'doe.net', 'john.doe.net', 'jane.doe.net' ] }
|
|
|
|
var secret = 'shhhhh';
|
|
|
|
var token = jwt.sign(tokenData, secret);
|
|
|
|
```
|
|
|
|
|
|
|
|
### net
|
|
|
|
|
|
|
|
Let's say you want to handle http requests in-process
|
|
|
|
or decrypt https before passing it to the local http handler.
|
2016-10-11 20:49:52 +00:00
|
|
|
|
|
|
|
You'll need to create a pair of streams to connect between the
|
|
|
|
local handler and the tunnel handler.
|
|
|
|
|
2016-10-06 21:01:58 +00:00
|
|
|
You could do a little magic like this:
|
|
|
|
|
2016-12-19 16:31:35 +00:00
|
|
|
```js
|
2016-10-06 21:01:58 +00:00
|
|
|
stunnel.connect({
|
|
|
|
// ...
|
|
|
|
, net: {
|
|
|
|
createConnection: function (info, cb) {
|
|
|
|
// data is the hello packet / first chunk
|
|
|
|
// info = { data, servername, port, host, remoteAddress: { family, address, port } }
|
|
|
|
|
2017-04-28 03:03:07 +00:00
|
|
|
var streamPair = require('stream-pair');
|
2018-02-15 06:27:15 +00:00
|
|
|
|
2017-04-28 02:47:41 +00:00
|
|
|
// here "reader" means the socket that looks like the connection being accepted
|
2017-04-28 03:03:07 +00:00
|
|
|
var writer = streamPair.create();
|
2017-04-28 02:47:41 +00:00
|
|
|
// here "writer" means the remote-looking part of the socket that driving the connection
|
2017-04-28 03:03:07 +00:00
|
|
|
var reader = writer.other;
|
2016-10-11 20:49:52 +00:00
|
|
|
// duplex = { write, push, end, events: [ 'readable', 'data', 'error', 'end' ] };
|
|
|
|
|
2017-04-28 02:47:41 +00:00
|
|
|
reader.remoteFamily = info.remoteFamily;
|
|
|
|
reader.remoteAddress = info.remoteAddress;
|
|
|
|
reader.remotePort = info.remotePort;
|
2016-10-06 21:01:58 +00:00
|
|
|
|
|
|
|
// socket.local{Family,Address,Port}
|
2017-04-28 02:47:41 +00:00
|
|
|
reader.localFamily = 'IPv4';
|
|
|
|
reader.localAddress = '127.0.01';
|
|
|
|
reader.localPort = info.port;
|
2016-10-06 21:01:58 +00:00
|
|
|
|
2017-04-28 02:47:41 +00:00
|
|
|
httpsServer.emit('connection', reader);
|
2016-10-06 21:01:58 +00:00
|
|
|
|
2016-10-11 19:57:21 +00:00
|
|
|
if (cb) {
|
2016-10-11 21:43:09 +00:00
|
|
|
process.nextTick(cb);
|
2016-10-11 19:57:21 +00:00
|
|
|
}
|
|
|
|
|
2017-04-28 02:47:41 +00:00
|
|
|
return writer;
|
2016-10-06 21:01:58 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
```
|