forked from coolaj86/telebit.js
		
	changed method for mapping services to local ports
This commit is contained in:
		
							parent
							
								
									ec245dff63
								
							
						
					
					
						commit
						646cfedabe
					
				
							
								
								
									
										104
									
								
								bin/stunnel.js
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								bin/stunnel.js
									
									
									
									
									
								
							| @ -13,7 +13,6 @@ function collectDomains(val, memo) { | |||||||
| 
 | 
 | ||||||
|   function parseProxy(location) { |   function parseProxy(location) { | ||||||
|     // john.example.com
 |     // john.example.com
 | ||||||
|     // https:3443
 |  | ||||||
|     // http:john.example.com:3000
 |     // http:john.example.com:3000
 | ||||||
|     // http://john.example.com:3000
 |     // http://john.example.com:3000
 | ||||||
|     var parts = location.split(':'); |     var parts = location.split(':'); | ||||||
| @ -144,19 +143,11 @@ function connectTunnel() { | |||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   program.locals.forEach(function (proxy) { |   Object.keys(program.services).forEach(function (protocol) { | ||||||
|     var port = proxy.port; |     var subServices = program.services[protocol]; | ||||||
|     if (!proxy.port) { |     Object.keys(subServices).forEach(function (hostname) { | ||||||
|       if ('http' === proxy.protocol) { |       console.info('[local proxy]', protocol + '://' + hostname + ' => ' + subServices[hostname]); | ||||||
|         port = hasHttp; |     }); | ||||||
|       } |  | ||||||
|       else if ('https' === proxy.protocol) { |  | ||||||
|         port = hasHttps; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     if (proxy.protocol) { |  | ||||||
|       console.info('[local proxy]', proxy.protocol + '://' + proxy.hostname + ' => ' + port); |  | ||||||
|     } |  | ||||||
|   }); |   }); | ||||||
|   console.info(''); |   console.info(''); | ||||||
| 
 | 
 | ||||||
| @ -179,22 +170,22 @@ function rawTunnel() { | |||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   if (!program.token) { | ||||||
|     var jwt = require('jsonwebtoken'); |     var jwt = require('jsonwebtoken'); | ||||||
|     var tokenData = { |     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)) { |   if (!location.protocol || /\./.test(location.protocol)) { | ||||||
|     program.stunneld = 'wss://' + program.stunneld; |     program.stunneld = 'wss://' + program.stunneld; | ||||||
|     location = url.parse(program.stunneld); |     location = url.parse(program.stunneld); | ||||||
|   } |   } | ||||||
|   program.stunneld = location.protocol + '//' + location.hostname + (location.port ? ':' + location.port : ''); |   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(); |   connectTunnel(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -234,45 +225,50 @@ function daplieTunnel() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var domainsMap = {}; | var domainsMap = {}; | ||||||
| var hasHttp; | var services = {}; | ||||||
| var hasHttps; |  | ||||||
| 
 | 
 | ||||||
| program.locals = program.locals || []; | program.locals = (program.locals || []).concat(program.domains || []); | ||||||
| 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.forEach(function (proxy) { | 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; |     domainsMap[proxy.hostname] = true; | ||||||
| }); |  | ||||||
| if (domainsMap.hasOwnProperty('*')) { |  | ||||||
|   delete domainsMap['*']; |  | ||||||
|   //domainsMap['*'] = false;
 |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   // 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 (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) { | if (!(program.secret || program.token) && !program.stunneld) { | ||||||
|   daplieTunnel(); |   daplieTunnel(); | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										28
									
								
								wsclient.js
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								wsclient.js
									
									
									
									
									
								
							| @ -7,13 +7,6 @@ var Packer = require('tunnel-packer'); | |||||||
| var authenticated = false; | var authenticated = false; | ||||||
| 
 | 
 | ||||||
| function run(copts) { | 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 tunnelUrl = copts.stunneld.replace(/\/$/, '') + '/?access_token=' + copts.token; | ||||||
|   var wstunneler; |   var wstunneler; | ||||||
|   var localclients = {}; |   var localclients = {}; | ||||||
| @ -26,9 +19,10 @@ function run(copts) { | |||||||
|     onmessage: function (opts) { |     onmessage: function (opts) { | ||||||
|       var net = copts.net || require('net'); |       var net = copts.net || require('net'); | ||||||
|       var cid = Packer.addrToId(opts); |       var cid = Packer.addrToId(opts); | ||||||
|       var service = opts.service; |       var service = opts.service.toLowerCase(); | ||||||
|       var port = copts.services[service]; |       var portList = copts.services[service]; | ||||||
|       var servername; |       var servername; | ||||||
|  |       var port; | ||||||
|       var str; |       var str; | ||||||
|       var m; |       var m; | ||||||
| 
 | 
 | ||||||
| @ -39,7 +33,12 @@ function run(copts) { | |||||||
|         localclients[cid].write(opts.data); |         localclients[cid].write(opts.data); | ||||||
|         return; |         return; | ||||||
|       } |       } | ||||||
|       else if ('http' === service) { |       if (!portList) { | ||||||
|  |         handlers._onLocalError(cid, opts, new Error("unsupported service '" + service + "'")); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if ('http' === service) { | ||||||
|         str = opts.data.toString(); |         str = opts.data.toString(); | ||||||
|         m = str.match(/(?:^|[\r\n])Host: ([^\r\n]+)[\r\n]*/im); |         m = str.match(/(?:^|[\r\n])Host: ([^\r\n]+)[\r\n]*/im); | ||||||
|         servername = (m && m[1].toLowerCase() || '').split(':')[0]; |         servername = (m && m[1].toLowerCase() || '').split(':')[0]; | ||||||
| @ -48,20 +47,19 @@ function run(copts) { | |||||||
|         servername = sni(opts.data); |         servername = sni(opts.data); | ||||||
|       } |       } | ||||||
|       else { |       else { | ||||||
|         handlers._onLocalError(cid, opts, new Error("unsupported service '" + service + "'")); |         servername = '*'; | ||||||
|         return; |  | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       if (!servername) { |       if (!servername) { | ||||||
|         console.info("[error] missing servername for '" + cid + "'", opts.data.byteLength); |  | ||||||
|         //console.warn(opts.data.toString());
 |         //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; |         return; | ||||||
|       } |       } | ||||||
|  |       port = portList[servername] || portList['*']; | ||||||
| 
 | 
 | ||||||
|       console.info("[connect] new client '" + cid + "' for '" + servername + "' (" + (handlers._numClients() + 1) + " clients)"); |       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({ |       localclients[cid] = net.createConnection({ | ||||||
|         port: port |         port: port | ||||||
|       , host: '127.0.0.1' |       , host: '127.0.0.1' | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user