Monday 12 June 2017

Piping HTTP 'CONNECT' requests to another net.Socket and getting the response back

I'm trying to set up a reverse proxy server that takes HTTP(S) requests and relays the requests to an exit node. The exit node will give a response back to the master server and the master proxy should return the result to the client that initiated the request.

Like this:

[CLIENT] ---HTTP(S) REQ---> [MASTER PROXY] --- RELAY REQ ---> [EXIT NODE]
   ^                                                            |
    \--- RELAY RESP --- [MASTER PROXY] <--- HTTP(S) RESP ------/

Insecure HTTP is easy. I'm using Net.Socket.Write for comm between master proxy & exit node.

Secure HTTPS is difficult. I don't want to throw cert errors. For a standard reverse proxy you'd pipe the TCP connection like this:

var http = require('http'),
    net = require('net'),
    httpProxy = require('http-proxy'),
    url = require('url'),
    util = require('util');

var proxy = httpProxy.createServer();

var server = http.createServer(function (req, res) {
  util.puts('Receiving reverse proxy request for:' + req.url);

  proxy.web(req, res, {target: req.url, secure: false});
}).listen(8213);

server.on('connect', function (req, socket) {
  util.puts('Receiving reverse proxy request for:' + req.url);

  var serverUrl = url.parse('https://' + req.url);

  var srvSocket = net.connect(serverUrl.port, serverUrl.hostname, function() {
    socket.write('HTTP/1.1 200 Connection Established\r\n' +
    'Proxy-agent: Node-Proxy\r\n' +
    '\r\n');
    srvSocket.pipe(socket); // pipe the connection to allow handshake directly between server/client
    socket.pipe(srvSocket); // pipe the connection to allow handshake directly between server/client
  });
});

But I can't figure out how to pipe to the exit node and get a valid response in plaintext all the way back to the requesting client. Does anyone have any suggestions on how to achieve this?



via rdbell

No comments:

Post a Comment