Node.js - forward all traffic from port A to port B

26,613

Solution 1

Here's my go at it:

Supports giving the "from" and "to" from command line, and supports remote machines.

var net = require('net');

// parse "80" and "localhost:80" or even "42mEANINg-life.com:80"
var addrRegex = /^(([a-zA-Z\-\.0-9]+):)?(\d+)$/;

var addr = {
    from: addrRegex.exec(process.argv[2]),
    to: addrRegex.exec(process.argv[3])
};

if (!addr.from || !addr.to) {
    console.log('Usage: <from> <to>');
    return;
}

net.createServer(function(from) {
    var to = net.createConnection({
        host: addr.to[2],
        port: addr.to[3]
    });
    from.pipe(to);
    to.pipe(from);
}).listen(addr.from[3], addr.from[2]);

(save as proxy.js)

To forward from localhost:9001 => localhost:80

$ node proxy.js 9001 80

Or localhost:9001 => otherhost:80

$ node proxy.js 9001 otherhost:80

(This was based on Andrey's answer, thanks!)

Solution 2

you need to have createConnection on one side. Here is the script I use to forward traffic

var net = require('net');

var sourceport = 1234;
var destport = 1235;

net.createServer(function(s)
{
    var buff = "";
    var connected = false;
    var cli = net.createConnection(destport);
    s.on('data', function(d) {
        if (connected)
        {
           cli.write(d);
        } else {
           buff += d.toString();
        }
    });
    cli.on('connect', function() {
        connected = true;
        cli.write(buff);
    });
    cli.pipe(s);
}).listen(sourceport);

Solution 3

Have you looked at the Node.js module Hoxy?

http://www.youtube.com/watch?v=2YLfBTrVgZU

Quick description from the developer's README:

Hoxy is a web-hacking proxy for node.js, intended for use by web developers. Using hoxy, you can act as a "man in the middle" and alter HTTP requests and responses as they flow through, based on a set of conditional rules. As a running process, hoxy otherwise behaves like a standalone proxy server. Hoxy was inspired as a way to complement debuggers like Firebug, which let you manipulate the client runtime but not the underlying HTTP conversation.

This should work pretty well unless you're looking for a lower level, packet to packet inspection of the data.

Share:
26,613

Related videos on Youtube

Eamorr
Author by

Eamorr

Updated on July 09, 2022

Comments

  • Eamorr
    Eamorr almost 2 years

    I'm trying to forward all traffic from port 6999 to port 7000 (I know I could use iptables, but the idea is to use Node.js to do some packet inspection).

    Here is the code I have sofar:

    var net=require('net');
    var compress=require('./node-compress/compress');
    
    var ip='172.16.1.224';
    var ipPort=6999;
    var opPort=7000;
    
    var output=net.createServer(function(connOut){
            var input=net.createServer(function(connIn){
                    connIn.pipe(connOut);
            });
            input.listen(ipPort,ip);
    });
    output.listen(opPort,ip);
    

    It just does not seem to work. When I do a tcpdump on port 7000, nothing shows up. Anyone have any suggestions?

    Many thanks in advance,

  • Eamorr
    Eamorr almost 13 years
    Hey, thanks for your response. I'm just going to have a look at Hoxy now. I am also hoping to compress and down-sample all the images using ImageMagick. It's for use on a satellite link...
  • slickplaid
    slickplaid almost 13 years
    No problem :) Let me know if this is something you're looking for or if you need something a bit more fine-grained or for TCP sockets and not HTTP data. Hoxy has been a lifesaver in quite a few situations for me.
  • Eamorr
    Eamorr almost 13 years
    You wouldn't know how I'd extract all images using Hoxy, would you? I'd like to compress them all... I'm hoping this is straightforward enough to do...
  • slickplaid
    slickplaid almost 13 years
    I'd have to take a closer look at the rule syntax, but given that you can alter the request and response body both ways, I'd imagine it'd be relatively easy to do. Have a look here for the rules syntax: github.com/greim/hoxy/tree/master/rules
  • Eamorr
    Eamorr almost 13 years
    Do you know how I'd compress the transmission using node-compress? I mean, how do I know whether to compress or decompress s or d? I've added this line: gunzip.init();cli.write(gunzip.inflate(d)+gunzip.end()); and this line gzip.init();cli.pipe(gzip.deflate(s)+gzip.end());, but I think I'm getting my compression/decompression mixed up. Many thanks in advance,
  • Andrey Sidorov
    Andrey Sidorov almost 13 years
    not quite sure what you mean. You have traffic A <-> B. Why do you need compression? Is your task 'forward data from A to B and decompress it, B to A and compress'?
  • Leonardo Spina
    Leonardo Spina over 7 years
    this is fantastic. Thanks!
  • Mario
    Mario about 2 years
    I believe the arguments of this are mistyped here. The correct usage of the current code is <to> <from> and not the other way around
  • joonas.fi
    joonas.fi about 2 years
    @Mario no, it's the right way round. I just tested by running $ node index.js 80 google.com:80 and it correctly forwards to Google, i.e. it's in format <from> <to>.
  • Yogurt
    Yogurt almost 2 years
    It's nice and lean, and it's working. However, to avoid crashing your app on network errors or leaving an open socket to the other side, you may want to add these below the pipe lines: ` from.on('error', (err) => { console.error('Error FROM: ', err); to.destroy(err); }); to.on('error', (err) => { console.error('Error TO: ', err); from.destroy(err); });`