forked from coolaj86/telebit.js
		
	tunnel via ws
This commit is contained in:
		
							parent
							
								
									9c7e3d1adf
								
							
						
					
					
						commit
						b24d12f84c
					
				| @ -23,6 +23,7 @@ | |||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "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", | ||||||
|  |     "ws": "^1.1.1" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										151
									
								
								wsclient.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								wsclient.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,151 @@ | |||||||
|  | (function () { | ||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var net = require('net'); | ||||||
|  | var WebSocket = require('ws'); | ||||||
|  | var jwt = require('jsonwebtoken'); | ||||||
|  | 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'
 | ||||||
|  | 
 | ||||||
|  | function addrToId(address) { | ||||||
|  |   return address.family + ',' + address.address + ',' + address.port; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | function socketToAddr(socket) { | ||||||
|  |   return { family: socket.remoteFamily, address: socket.remoteAddress, port: socket.remotePort }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function socketToId(socket) { | ||||||
|  |   return addrToId(socketToAddr(socket)); | ||||||
|  | } | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | var token = jwt.sign({ name: hostname }, 'shhhhh'); | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | var request = require('request'); | ||||||
|  | request.get('https://pokemap.hellabit.com:3000?access_token=' + token, { rejectUnauthorized: false }, function (err, resp) { | ||||||
|  |   console.log('resp.body'); | ||||||
|  |   console.log(resp.body); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | return; | ||||||
|  | //*/
 | ||||||
|  | 
 | ||||||
|  | var wstunneler = new WebSocket('wss://pokemap.hellabit.com:3000/?access_token=' + token, { rejectUnauthorized: false }); | ||||||
|  | wstunneler.on('open', function () { | ||||||
|  |   console.log('[open] tunneler connected'); | ||||||
|  |   var localclients = {}; | ||||||
|  | 
 | ||||||
|  |   /* | ||||||
|  |   setInterval(function () { | ||||||
|  |     console.log(''); | ||||||
|  |     console.log('localclients.length:', Object.keys(localclients).length); | ||||||
|  |     console.log(''); | ||||||
|  |   }, 5000); | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  |   //wstunneler.send(token);
 | ||||||
|  | 
 | ||||||
|  |   // BaaS / Backendless / noBackend / horizon.io
 | ||||||
|  |   // user authentication
 | ||||||
|  |   // a place to store data
 | ||||||
|  |   // file management
 | ||||||
|  |   // Synergy Teamwork Paradigm = Jabberwocky
 | ||||||
|  |   var pack = require('tunnel-packer').pack; | ||||||
|  | 
 | ||||||
|  |   function onMessage(opts) { | ||||||
|  |     var cid = addrToId(opts); | ||||||
|  |     console.log('[wsclient] onMessage:', cid); | ||||||
|  |     var service = opts.service; | ||||||
|  |     var port = services[service]; | ||||||
|  |     var lclient; | ||||||
|  |     var servername; | ||||||
|  |     var str; | ||||||
|  |     var m; | ||||||
|  | 
 | ||||||
|  |     if (opts.data.byteLength < 20) { | ||||||
|  |       if ('|__ERROR__|' === opts.data.toString('ascii') | ||||||
|  |         || '|__END__|' === opts.data.toString('ascii')) { | ||||||
|  | 
 | ||||||
|  |         console.log("['" + opts.data.toString('ascii') + "'] '" + cid + "'"); | ||||||
|  |         if (localclients[cid]) { | ||||||
|  |           localclients[cid].end(); | ||||||
|  |           delete localclients[cid]; | ||||||
|  |         } | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function endWithError() { | ||||||
|  |       wstunneler.send(pack(opts, Buffer.from('|__ERROR__|')), { binary: true }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (localclients[cid]) { | ||||||
|  |       console.log("[=>] received data from '" + cid + "' =>", opts.data.byteLength); | ||||||
|  |       localclients[cid].write(opts.data); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     else 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]; | ||||||
|  |     } | ||||||
|  |     else if ('https' === service) { | ||||||
|  |       servername = sni(opts.data); | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       endWithError(); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!servername) { | ||||||
|  |       console.warn("|__ERROR__| no servername found for '" + cid + "'"); | ||||||
|  |       console.warn(opts.data.toString()); | ||||||
|  |       wstunneler.send(pack(opts, Buffer.from('|__ERROR__|')), { binary: true }); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     console.log("servername: '" + servername + "'"); | ||||||
|  | 
 | ||||||
|  |     lclient = localclients[cid] = net.createConnection({ port: port, host: '127.0.0.1' }, function () { | ||||||
|  | 
 | ||||||
|  |       lclient.on('data', function (chunk) { | ||||||
|  |         console.log("[<=] local '" + opts.service + "' sent to '" + cid + "' <= ", chunk.byteLength, "bytes"); | ||||||
|  |         console.log(JSON.stringify(chunk.toString())); | ||||||
|  |         wstunneler.send(pack(opts, chunk), { binary: true }); | ||||||
|  |       }); | ||||||
|  |       lclient.on('error', function (err) { | ||||||
|  |         console.error("[error] local '" + opts.service + "' '" + cid + "'"); | ||||||
|  |         console.error(err); | ||||||
|  |         delete localclients[cid]; | ||||||
|  |         wstunneler.send(pack(opts, Buffer.from('|__ERROR__|')), { binary: true }); | ||||||
|  |       }); | ||||||
|  |       lclient.on('end', function () { | ||||||
|  |         console.log("[end] local '" + opts.service + "' '" + cid + "'"); | ||||||
|  |         delete localclients[cid]; | ||||||
|  |         wstunneler.send(pack(opts, Buffer.from('|__END__|')), { binary: true }); | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       console.log("[=>] first packet from tunneler to '" + cid + "' as '" + opts.service + "'", opts.data.byteLength); | ||||||
|  |       lclient.write(opts.data); | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   var machine = require('tunnel-packer').create({ onMessage: onMessage }); | ||||||
|  | 
 | ||||||
|  |   wstunneler.on('message', machine.fns.addChunk); | ||||||
|  | 
 | ||||||
|  |   wstunneler.on('close', function () { | ||||||
|  |     console.log('end'); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | }()); | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user