changed method for mapping services to local ports
This commit is contained in:
		
							parent
							
								
									ec245dff63
								
							
						
					
					
						commit
						646cfedabe
					
				
							
								
								
									
										102
									
								
								bin/stunnel.js
									
									
									
									
									
								
							
							
						
						
									
										102
									
								
								bin/stunnel.js
									
									
									
									
									
								
							| @ -13,7 +13,6 @@ function collectDomains(val, memo) { | ||||
| 
 | ||||
|   function parseProxy(location) { | ||||
|     // john.example.com
 | ||||
|     // https:3443
 | ||||
|     // http:john.example.com:3000
 | ||||
|     // http://john.example.com:3000
 | ||||
|     var parts = location.split(':'); | ||||
| @ -144,19 +143,11 @@ function connectTunnel() { | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   program.locals.forEach(function (proxy) { | ||||
|     var port = proxy.port; | ||||
|     if (!proxy.port) { | ||||
|       if ('http' === proxy.protocol) { | ||||
|         port = hasHttp; | ||||
|       } | ||||
|       else if ('https' === proxy.protocol) { | ||||
|         port = hasHttps; | ||||
|       } | ||||
|     } | ||||
|     if (proxy.protocol) { | ||||
|       console.info('[local proxy]', proxy.protocol + '://' + proxy.hostname + ' => ' + 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(''); | ||||
| 
 | ||||
| @ -179,22 +170,22 @@ function rawTunnel() { | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   if (!program.token) { | ||||
|     var jwt = require('jsonwebtoken'); | ||||
|     var tokenData = { | ||||
|     domains: null | ||||
|       domains: Object.keys(domainsMap).filter(Boolean) | ||||
|     }; | ||||
|   var location = url.parse(program.stunneld); | ||||
| 
 | ||||
|     program.token = jwt.sign(tokenData, program.secret); | ||||
|   } | ||||
| 
 | ||||
|   var location = url.parse(program.stunneld); | ||||
|   if (!location.protocol || /\./.test(location.protocol)) { | ||||
|     program.stunneld = 'wss://' + program.stunneld; | ||||
|     location = url.parse(program.stunneld); | ||||
|   } | ||||
|   program.stunneld = location.protocol + '//' + location.hostname + (location.port ? ':' + location.port : ''); | ||||
| 
 | ||||
|   tokenData.domains = Object.keys(domainsMap).filter(Boolean); | ||||
| 
 | ||||
|   program.token = program.token || jwt.sign(tokenData, program.secret); | ||||
| 
 | ||||
|   connectTunnel(); | ||||
| } | ||||
| 
 | ||||
| @ -234,45 +225,50 @@ function daplieTunnel() { | ||||
| } | ||||
| 
 | ||||
| var domainsMap = {}; | ||||
| var hasHttp; | ||||
| var hasHttps; | ||||
| var services = {}; | ||||
| 
 | ||||
| program.locals = program.locals || []; | ||||
| program.locals = program.locals.concat(program.domains || []); | ||||
| program.locals.forEach(function (proxy) { | ||||
|   if ('*' === proxy.hostname) { | ||||
|     if ('http' === proxy.protocol) { | ||||
|       hasHttp = proxy.port; | ||||
|     } | ||||
|     else if ('https' === proxy.protocol) { | ||||
|       hasHttps = proxy.port; | ||||
|     } | ||||
|   } | ||||
| }); | ||||
| if (!hasHttp) { | ||||
|   program.locals.push({ | ||||
|     protocol: 'http' | ||||
|   , hostname: '*' | ||||
|   , port: 8443 | ||||
|   }); | ||||
|   hasHttp = 8443; | ||||
| } | ||||
| if (!hasHttps) { | ||||
|   program.locals.push({ | ||||
|     protocol: 'https' | ||||
|   , hostname: '*' | ||||
|   , port: 8443 | ||||
|   }); | ||||
|   hasHttps = 8443; | ||||
| } | ||||
| 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.
 | ||||
|   if (proxy.hostname && proxy.hostname !== '*') { | ||||
|     domainsMap[proxy.hostname] = true; | ||||
|   } | ||||
| 
 | ||||
|   // Create a map of which port different protocols should be forwarded to, allowing for specific
 | ||||
|   // domains to go to different ports if need be (though that only works for HTTP and HTTPS).
 | ||||
|   if (proxy.protocol && proxy.port) { | ||||
|     services[proxy.protocol] = services[proxy.protocol] || {}; | ||||
| 
 | ||||
|     if (/http/.test(proxy.protocol) && proxy.hostname && proxy.hostname !== '*') { | ||||
|       services[proxy.protocol][proxy.hostname] = proxy.port; | ||||
|     } | ||||
|     else { | ||||
|       if (services[proxy.protocol]['*'] && services[proxy.protocol]['*'] !== proxy.port) { | ||||
|         console.error('cannot forward generic', proxy.protocol, 'traffic to multiple ports'); | ||||
|         process.exit(1); | ||||
|       } | ||||
|       else { | ||||
|         services[proxy.protocol]['*'] = proxy.port; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| }); | ||||
| if (domainsMap.hasOwnProperty('*')) { | ||||
|   delete domainsMap['*']; | ||||
|   //domainsMap['*'] = false;
 | ||||
| 
 | ||||
| if (Object.keys(domainsMap).length === 0) { | ||||
|   console.error('no domains specified'); | ||||
|   process.exit(1); | ||||
|   return; | ||||
| } | ||||
| 
 | ||||
| // Make sure we have generic ports for HTTP and HTTPS
 | ||||
| services.https = services.https || {}; | ||||
| services.https['*'] = services.https['*'] || 8443; | ||||
| 
 | ||||
| services.http = services.http || {}; | ||||
| services.http['*'] = services.http['*'] || services.https['*']; | ||||
| 
 | ||||
| program.services = services; | ||||
| 
 | ||||
| if (!(program.secret || program.token) && !program.stunneld) { | ||||
|   daplieTunnel(); | ||||
| } | ||||
|  | ||||
							
								
								
									
										28
									
								
								wsclient.js
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								wsclient.js
									
									
									
									
									
								
							| @ -7,13 +7,6 @@ var Packer = require('tunnel-packer'); | ||||
| var authenticated = false; | ||||
| 
 | ||||
| function run(copts) { | ||||
|   // TODO pair with hostname / sni
 | ||||
|   copts.services = {}; | ||||
|   copts.locals.forEach(function (proxy) { | ||||
|     //program.services = { 'ssh': 22, 'http': 80, 'https': 443 };
 | ||||
|     copts.services[proxy.protocol] = proxy.port; | ||||
|   }); | ||||
| 
 | ||||
|   var tunnelUrl = copts.stunneld.replace(/\/$/, '') + '/?access_token=' + copts.token; | ||||
|   var wstunneler; | ||||
|   var localclients = {}; | ||||
| @ -26,9 +19,10 @@ function run(copts) { | ||||
|     onmessage: function (opts) { | ||||
|       var net = copts.net || require('net'); | ||||
|       var cid = Packer.addrToId(opts); | ||||
|       var service = opts.service; | ||||
|       var port = copts.services[service]; | ||||
|       var service = opts.service.toLowerCase(); | ||||
|       var portList = copts.services[service]; | ||||
|       var servername; | ||||
|       var port; | ||||
|       var str; | ||||
|       var m; | ||||
| 
 | ||||
| @ -39,7 +33,12 @@ function run(copts) { | ||||
|         localclients[cid].write(opts.data); | ||||
|         return; | ||||
|       } | ||||
|       else if ('http' === service) { | ||||
|       if (!portList) { | ||||
|         handlers._onLocalError(cid, opts, new Error("unsupported service '" + service + "'")); | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
|       if ('http' === service) { | ||||
|         str = opts.data.toString(); | ||||
|         m = str.match(/(?:^|[\r\n])Host: ([^\r\n]+)[\r\n]*/im); | ||||
|         servername = (m && m[1].toLowerCase() || '').split(':')[0]; | ||||
| @ -48,20 +47,19 @@ function run(copts) { | ||||
|         servername = sni(opts.data); | ||||
|       } | ||||
|       else { | ||||
|         handlers._onLocalError(cid, opts, new Error("unsupported service '" + service + "'")); | ||||
|         return; | ||||
|         servername = '*'; | ||||
|       } | ||||
| 
 | ||||
|       if (!servername) { | ||||
|         console.info("[error] missing servername for '" + cid + "'", opts.data.byteLength); | ||||
|         //console.warn(opts.data.toString());
 | ||||
|         wstunneler.send(Packer.pack(opts, null, 'error'), { binary: true }); | ||||
|         handlers._onLocalError(cid, opts, new Error("missing servername for '" + cid + "' " + opts.data.byteLength)); | ||||
|         return; | ||||
|       } | ||||
|       port = portList[servername] || portList['*']; | ||||
| 
 | ||||
|       console.info("[connect] new client '" + cid + "' for '" + servername + "' (" + (handlers._numClients() + 1) + " clients)"); | ||||
| 
 | ||||
|       console.log('port', port, opts.port, service, copts.services); | ||||
|       console.log('port', port, opts.port, service, portList); | ||||
|       localclients[cid] = net.createConnection({ | ||||
|         port: port | ||||
|       , host: '127.0.0.1' | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user