| 
									
										
										
										
											2018-04-24 01:54:39 +00:00
										 |  |  | | Sponsored by [ppl](https://ppl.family) | [tunnel-server.js](https://git.coolaj86.com/coolaj86/tunnel-server.js) | **tunnel-client.js** | | 
					
						
							| 
									
										
										
										
											2018-04-24 01:54:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-30 12:33:38 -04:00
										 |  |  | # stunnel.js
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-14 23:27:15 -07:00
										 |  |  | A client that works in combination with [stunneld.js](https://git.coolaj86.com/coolaj86/tunnel-server.js) | 
					
						
							| 
									
										
										
										
											2016-09-30 18:07:26 -04:00
										 |  |  | to allow you to serve http and https from any computer, anywhere through a secure tunnel. | 
					
						
							| 
									
										
										
										
											2016-09-30 12:33:38 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 15:01:58 -06:00
										 |  |  | * CLI | 
					
						
							|  |  |  | * Library | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-30 12:33:38 -04: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 16:36:01 -06:00
										 |  |  | ```bash | 
					
						
							| 
									
										
										
										
											2018-02-14 23:27:15 -07:00
										 |  |  | npm install -g 'git+https://git@git.coolaj86.com/coolaj86/tunnel-client.js.git#v1' | 
					
						
							| 
									
										
										
										
											2017-04-05 16:36:01 -06:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Or if you want to bow down to the kings of the centralized dictator-net: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-30 12:33:38 -04:00
										 |  |  | ```bash | 
					
						
							|  |  |  | npm install -g stunnel | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-28 15:31:45 -06:00
										 |  |  | ### Usage with OAuth3.org
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-14 23:27:15 -07:00
										 |  |  | The OAuth3.org tunnel service is in Beta. | 
					
						
							| 
									
										
										
										
											2017-03-28 15:31:45 -06: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 12:33:38 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | How to use `stunnel.js` with your own instance of `stunneld.js`: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-26 01:37:26 -06:00
										 |  |  | ```bash | 
					
						
							|  |  |  | stunnel.js \ | 
					
						
							|  |  |  |   --locals <<external domain name>> \ | 
					
						
							|  |  |  |   --stunneld wss://<<tunnel domain>>:<<tunnel port>> \ | 
					
						
							|  |  |  |   --secret <<128-bit hex key>> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-30 12:33:38 -04:00
										 |  |  | ```bash | 
					
						
							| 
									
										
										
										
											2016-10-06 15:16:21 -06:00
										 |  |  | stunnel.js --locals john.example.com --stunneld wss://tunnel.example.com:443 --secret abc123 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-26 01:37:26 -06: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 15:16:21 -06: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 12:33:38 -04: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 15:01:58 -06: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 15:39:06 -06:00
										 |  |  | * You can get sneaky with `net` and provide a `createConnection` that returns a `stream.Duplex`. | 
					
						
							| 
									
										
										
										
											2016-10-06 15:01:58 -06: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 14:49:52 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | You'll need to create a pair of streams to connect between the | 
					
						
							|  |  |  | local handler and the tunnel handler. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 15:01:58 -06:00
										 |  |  | You could do a little magic like this: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-19 09:31:35 -07:00
										 |  |  | ```js | 
					
						
							| 
									
										
										
										
											2016-10-06 15:01:58 -06: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-14 23:27:15 -07: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 14:49:52 -06: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 15:01:58 -06: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 15:01:58 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-28 02:47:41 +00:00
										 |  |  |     httpsServer.emit('connection', reader); | 
					
						
							| 
									
										
										
										
											2016-10-06 15:01:58 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-11 13:57:21 -06:00
										 |  |  |     if (cb) { | 
					
						
							| 
									
										
										
										
											2016-10-11 15:43:09 -06:00
										 |  |  |       process.nextTick(cb); | 
					
						
							| 
									
										
										
										
											2016-10-11 13:57:21 -06:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-28 02:47:41 +00:00
										 |  |  |     return writer; | 
					
						
							| 
									
										
										
										
											2016-10-06 15:01:58 -06:00
										 |  |  |   } | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` |