moving towards release
This commit is contained in:
		
							parent
							
								
									4d9dcdd7c6
								
							
						
					
					
						commit
						62a7fb7777
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,3 +1,5 @@ | |||||||
|  | node_modules.* | ||||||
|  | 
 | ||||||
| # Logs | # Logs | ||||||
| logs | logs | ||||||
| *.log | *.log | ||||||
|  | |||||||
							
								
								
									
										47
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								README.md
									
									
									
									
									
								
							| @ -1,2 +1,45 @@ | |||||||
| # node-tunnel-client | # stunnel.js | ||||||
| A paired client for our node tunnel server | 
 | ||||||
|  | Works in combination with [stunneld.js](https://github.com/Daplie/node-tunnel-server) | ||||||
|  | to allow you to serve http and https from provide a secure tunnelA paired client for our node tunnel server | ||||||
|  | 
 | ||||||
|  | CLI | ||||||
|  | === | ||||||
|  | 
 | ||||||
|  | Installs as `stunnel.js` with the alias `jstunnel` | ||||||
|  | (for those that regularly use `stunnel` but still like commandline completion). | ||||||
|  | 
 | ||||||
|  | ### Install | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | npm install -g stunnel | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Advanced Usage | ||||||
|  | 
 | ||||||
|  | How to use `stunnel.js` with your own instance of `stunneld.js`: | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | stunnel.js --locals http:john.example.com:3000,https:john.example.com --stunneld https://tunnel.example.com:443 --secret abc123 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | --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 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Usage | ||||||
|  | 
 | ||||||
|  | **NOT YET IMPLEMENTED** | ||||||
|  | 
 | ||||||
|  | Daplie's tunneling service is not yet publicly available. | ||||||
|  | 
 | ||||||
|  | **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:john.example.com:4080,https:john.example.com:8443 | ||||||
|  | ``` | ||||||
|  | |||||||
							
								
								
									
										6
									
								
								TODO.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								TODO.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | |||||||
|  | TODO | ||||||
|  | 
 | ||||||
|  |   * [*] Work with Secure WebSockets | ||||||
|  |   * [ ] Hijack HTTPS connection directly (without WebSockets) | ||||||
|  |   * [p] Raw TCP (for transporting https once, not twice) (partial) | ||||||
|  |   * [ ] Let's Encrypt Support (for connecting to a plain http server locally) | ||||||
							
								
								
									
										70
									
								
								bin/stunnel.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								bin/stunnel.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | |||||||
|  | (function () { | ||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var pkg = require('../package.json'); | ||||||
|  | 
 | ||||||
|  | var program = require('commander'); | ||||||
|  | var stunnel = require('../wsclient.js'); | ||||||
|  | 
 | ||||||
|  | function collectProxies(val, memo) { | ||||||
|  |   var vals = val.split(/,/g); | ||||||
|  |   vals.map(function (location) { | ||||||
|  |     // http:john.example.com:3000
 | ||||||
|  |     // http://john.example.com:3000
 | ||||||
|  |     var parts = location.split(':'); | ||||||
|  |     parts[0] = parts[0].toLowerCase(); | ||||||
|  |     parts[1] = parts[1].toLowerCase().replace(/(\/\/)?/, '') || '*'; | ||||||
|  |     parts[2] = parseInt(parts[2], 10) || 0; | ||||||
|  |     if (!parts[2]) { | ||||||
|  |       // TODO grab OS list of standard ports?
 | ||||||
|  |       if ('http' === parts[0]) { | ||||||
|  |         parts[2] = 80; | ||||||
|  |       } | ||||||
|  |       else if ('https' === parts[0]) { | ||||||
|  |         parts[2] = 443; | ||||||
|  |       } | ||||||
|  |       else { | ||||||
|  |         throw new Error("port must be specified - ex: tls:*:1337"); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return { | ||||||
|  |       protocol: parts[0] | ||||||
|  |     , hostname: parts[1] | ||||||
|  |     , port: parts[2] | ||||||
|  |     }; | ||||||
|  |   }).forEach(memo.push); | ||||||
|  | 
 | ||||||
|  |   return memo; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | program | ||||||
|  |   .version(pkg.version) | ||||||
|  |   //.command('jsurl <url>')
 | ||||||
|  |   .arguments('<url>') | ||||||
|  |   .action(function (url) { | ||||||
|  |     program.url = url; | ||||||
|  |   }) | ||||||
|  |   .option('-k --insecure', 'Allow TLS connections to stunneld without valid certs (H)') | ||||||
|  |   .option('--locals <LINE>', 'comma separated list of <proto>:<//><servername>:<port> to which matching incoming http and https should forward (reverse proxy). Ex: https://john.example.com,tls:*:1337', collectProxies, [ ]) // --reverse-proxies
 | ||||||
|  |   .option('--stunneld <URL>', 'the domain (or ip address) at which you are running stunneld.js (the proxy)') // --proxy
 | ||||||
|  |   .option('--secret', 'the same secret used by stunneld (used for JWT authentication)') | ||||||
|  |   .option('--token', 'a pre-generated token for use with stunneld (instead of generating one with --secret)') | ||||||
|  |   .parse(process.argv) | ||||||
|  |   ; | ||||||
|  | 
 | ||||||
|  | // Assumption: will not get next tcp packet unless previous packet succeeded
 | ||||||
|  | var hostname = 'aj.daplie.me'; // 'pokemap.hellabit.com'
 | ||||||
|  | var jwt = require('jsonwebtoken'); | ||||||
|  | 
 | ||||||
|  | program.services = {}; | ||||||
|  | program.locals.forEach(function (proxy) { | ||||||
|  |   //program.services = { 'ssh': 22, 'http': 80, 'https': 443 };
 | ||||||
|  |   program.services[proxy.protocol] = proxy.port; | ||||||
|  | }); | ||||||
|  | program.token = program.token || jwt.sign({ name: hostname }, program.secret || 'shhhhh'); | ||||||
|  | program.stunneld = program.stunneld || 'wss://pokemap.hellabit.com:3000'; | ||||||
|  | 
 | ||||||
|  | stunnel.connect(program); | ||||||
|  | 
 | ||||||
|  | }()); | ||||||
							
								
								
									
										33
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								package.json
									
									
									
									
									
								
							| @ -1,8 +1,12 @@ | |||||||
| { | { | ||||||
|   "name": "tunnel-client", |   "name": "stunnel", | ||||||
|   "version": "1.0.0", |   "version": "0.8.0", | ||||||
|   "description": "A naive tunnel client", |   "description": "A pure-JavaScript tunnel client for http and https similar to localtunnel.me, but uses TLS (SSL) with ServerName Indication (SNI) over https to work even in harsh network conditions such as in student dorms and behind HOAs, corporate firewalls, public libraries, airports, airplanes, etc. Can also tunnel tls and plain tcp.", | ||||||
|   "main": "client.js", |   "main": "wsclient.js", | ||||||
|  |   "bin": { | ||||||
|  |     "jstunnel": "bin/stunnel.js", | ||||||
|  |     "stunnel-js": "bin/stunnel.js" | ||||||
|  |   }, | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "test": "echo \"Error: no test specified\" && exit 1" |     "test": "echo \"Error: no test specified\" && exit 1" | ||||||
|   }, |   }, | ||||||
| @ -12,7 +16,25 @@ | |||||||
|   }, |   }, | ||||||
|   "keywords": [ |   "keywords": [ | ||||||
|     "tcp", |     "tcp", | ||||||
|     "tunnel" |     "tls", | ||||||
|  |     "http", | ||||||
|  |     "https", | ||||||
|  |     "sni", | ||||||
|  |     "servername", | ||||||
|  |     "indication", | ||||||
|  |     "stunnel", | ||||||
|  |     "secure", | ||||||
|  |     "securetunnel", | ||||||
|  |     "secure-tunnel", | ||||||
|  |     "tunnel", | ||||||
|  |     "localtunnel", | ||||||
|  |     "localtunnel.me", | ||||||
|  |     "proxy", | ||||||
|  |     "reverse", | ||||||
|  |     "reverse-proxy", | ||||||
|  |     "reverseproxy", | ||||||
|  |     "vpn", | ||||||
|  |     "sni" | ||||||
|   ], |   ], | ||||||
|   "author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)", |   "author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)", | ||||||
|   "license": "(MIT OR Apache-2.0)", |   "license": "(MIT OR Apache-2.0)", | ||||||
| @ -21,6 +43,7 @@ | |||||||
|   }, |   }, | ||||||
|   "homepage": "https://github.com/Daplie/node-tunnel-client#readme", |   "homepage": "https://github.com/Daplie/node-tunnel-client#readme", | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|  |     "commander": "^2.9.0", | ||||||
|     "jsonwebtoken": "^7.1.9", |     "jsonwebtoken": "^7.1.9", | ||||||
|     "sni": "^1.0.0", |     "sni": "^1.0.0", | ||||||
|     "tunnel-packer": "^1.0.0", |     "tunnel-packer": "^1.0.0", | ||||||
|  | |||||||
							
								
								
									
										19
									
								
								snippets/ws.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								snippets/ws.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | (function () { | ||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var WebSocket = require('ws'); | ||||||
|  | var jwt = require('jsonwebtoken'); | ||||||
|  | var hostname = 'example.daplie.me'; | ||||||
|  | var token = jwt.sign({ name: hostname }, 'shhhhh'); | ||||||
|  | var url = 'wss://stunnel.hellabit.com:3000/?access_token=' + token; | ||||||
|  | var wstunneler = new WebSocket(url, { rejectUnauthorized: false }); | ||||||
|  | 
 | ||||||
|  | wstunneler.on('open', function () { | ||||||
|  |   console.log('open'); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | wstunneler.on('error', function (err) { | ||||||
|  |   console.error(err.toString()); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | }()); | ||||||
							
								
								
									
										21
									
								
								wsclient.js
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								wsclient.js
									
									
									
									
									
								
							| @ -3,16 +3,9 @@ | |||||||
| 
 | 
 | ||||||
| var net = require('net'); | var net = require('net'); | ||||||
| var WebSocket = require('ws'); | var WebSocket = require('ws'); | ||||||
| var jwt = require('jsonwebtoken'); |  | ||||||
| var sni = require('sni'); | var sni = require('sni'); | ||||||
| // TODO ask oauth3.org where to connect
 |  | ||||||
| // TODO reconnect on disconnect
 |  | ||||||
| 
 |  | ||||||
| // Assumption: will not get next tcp packet unless previous packet succeeded
 |  | ||||||
| //var services = { 'ssh': 22, 'http': 80, 'https': 443 };
 |  | ||||||
| var services = { 'ssh': 22, 'http': 4080, 'https': 8443 }; |  | ||||||
| var hostname = 'aj.daplie.me'; // 'pokemap.hellabit.com'
 |  | ||||||
| 
 | 
 | ||||||
|  | // TODO move these helpers to tunnel-packer package
 | ||||||
| function addrToId(address) { | function addrToId(address) { | ||||||
|   return address.family + ',' + address.address + ',' + address.port; |   return address.family + ',' + address.address + ',' + address.port; | ||||||
| } | } | ||||||
| @ -27,7 +20,6 @@ function socketToId(socket) { | |||||||
| } | } | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| var token = jwt.sign({ name: hostname }, 'shhhhh'); |  | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
| var request = require('request'); | var request = require('request'); | ||||||
| @ -39,10 +31,11 @@ request.get('https://pokemap.hellabit.com:3000?access_token=' + token, { rejectU | |||||||
| return; | return; | ||||||
| //*/
 | //*/
 | ||||||
| 
 | 
 | ||||||
|   var tunnelUrl = 'wss://pokemap.hellabit.com:3000/?access_token=' + token; |   function run(copts) { | ||||||
|   var wstunneler; |     var services = copts.services; // TODO pair with hostname / sni
 | ||||||
| 
 |     var token = copts.token; | ||||||
|   function run() { |     var tunnelUrl = copts.stunneld + '/?access_token=' + token; | ||||||
|  |     var wstunneler; | ||||||
|     var retry = true; |     var retry = true; | ||||||
|     var localclients = {}; |     var localclients = {}; | ||||||
|     wstunneler = new WebSocket(tunnelUrl, { rejectUnauthorized: false }); |     wstunneler = new WebSocket(tunnelUrl, { rejectUnauthorized: false }); | ||||||
| @ -205,5 +198,5 @@ return; | |||||||
|     process.on('SIGINT', onExit); |     process.on('SIGINT', onExit); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   run(); |   module.exports.connect = run; | ||||||
| }()); | }()); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user