Skip to content

Instantly share code, notes, and snippets.

@root-ali
Forked from kfox/tcpproxy.js
Last active February 19, 2020 07:16
Show Gist options
  • Save root-ali/0ceed88c7579bf255b90fa4280950781 to your computer and use it in GitHub Desktop.
Save root-ali/0ceed88c7579bf255b90fa4280950781 to your computer and use it in GitHub Desktop.
A basic TCP proxy written in node.js with dynamic remote host
#!/usr/bin/env node
const net = require('net');
process.on('uncaughtException', function(error) {
console.error(error);
});
const localPortHttp = process.argv[2];
const localPortHttps = process.argv[3];
let server = net.createServer(function(localsocket) {
const remoteSocket = new net.Socket();
const obj = { count: 0 };
// remoteSocket.connect(remotePort, remoteHost);
localsocket.on('connect', function(data) {
console.log('>>> connection #%d from %s:%d',
server.connections,
localsocket.remoteAddress,
localsocket.remotePort,
);
});
localsocket.on('data', function(data) {
console.log('%s:%d - writing data to remote',
localsocket.remoteAddress,
localsocket.remotePort,
);
if (obj.count === 0) {
let host = data.toString().replace(/\r?\n|\r/g, " ").split(":")[1].split(" ")[1];
remoteSocket.connect(localPortHttp, host);
obj.count++;
}
let flushed = remoteSocket.write(data);
if (!flushed) {
console.log(' remote not flushed; pausing local');
localsocket.pause();
}
});
remoteSocket.on('data', function(data) {
console.log('%s:%d - writing data to local',
localsocket.remoteAddress,
localsocket.remotePort,
);
console.log('send to local:', data.toString());
let flushed = localsocket.write(data);
if (!flushed) {
console.log(' local not flushed; pausing remote');
remoteSocket.pause();
}
});
localsocket.on('drain', function() {
console.log('%s:%d - resuming remote',
localsocket.remoteAddress,
localsocket.remotePort,
);
remoteSocket.resume();
});
remoteSocket.on('drain', function() {
console.log('%s:%d - resuming local',
localsocket.remoteAddress,
localsocket.remotePort,
);
localsocket.resume();
});
localsocket.on('close', function(had_error) {
console.log('%s:%d - closing remote',
localsocket.remoteAddress,
localsocket.remotePort,
);
remoteSocket.end();
});
remoteSocket.on('close', function(had_error) {
console.log('%s:%d - closing local',
localsocket.remoteAddress,
localsocket.remotePort,
);
localsocket.end();
});
});
let serverHttps = net.createServer(function(localsocket) {
const remoteSocket = new net.Socket();
const obj = { count: 0 };
localsocket.on('connect', function(data) {
console.log('>>> connection #%d from %s:%d',
server.connections,
localsocket.remoteAddress,
localsocket.remotePort,
);
});
localsocket.on('data', function(data) {
console.log('%s:%d - writing data to remote',
localsocket.remoteAddress,
localsocket.remotePort,
);
if (obj.count === 0) {
let host = data.toString().replace(/[^\x20-\x7E]/g, '').replace(/[^.,1-9a-z ]/g, ' ').split(' ');
host = longest_string(host);
remoteSocket.connect(localPortHttps, host[0]);
obj.count++;
}
let flushed = remoteSocket.write(data);
if (!flushed) {
console.log(' remote not flushed; pausing local');
localsocket.pause();
}
});
remoteSocket.on('data', function(data) {
console.log('%s:%d - writing data to local',
localsocket.remoteAddress,
localsocket.remotePort,
);
console.log('send to local:', data.toString());
let flushed = localsocket.write(data);
if (!flushed) {
console.log(' local not flushed; pausing remote');
remoteSocket.pause();
}
});
localsocket.on('drain', function() {
console.log('%s:%d - resuming remote',
localsocket.remoteAddress,
localsocket.remotePort,
);
remoteSocket.resume();
});
remoteSocket.on('drain', function() {
console.log('%s:%d - resuming local',
localsocket.remoteAddress,
localsocket.remotePort,
);
localsocket.resume();
});
localsocket.on('close', function(had_error) {
console.log('%s:%d - closing remote',
localsocket.remoteAddress,
localsocket.remotePort,
);
remoteSocket.end();
});
remoteSocket.on('close', function(had_error) {
console.log('%s:%d - closing local',
localsocket.remoteAddress,
localsocket.remotePort,
);
localsocket.end();
});
});
function longest_string(str_ara) {
var max = str_ara[0].length;
str_ara.map(v => max = Math.max(max, v.length));
result = str_ara.filter(v => v.length == max);
return result;
}
server.listen(localPortHttp , '0.0.0.0');
serverHttps.listen(localPortHttps , '0.0.0.0');
console.log('redirecting connections from 0.0.0.0:%d and 0.0.0.0:%s', localPortHttp , localPortHttps);
// For running the proxy execute this:
// ./proxy.js 80 443
// This would run proxy on port 80 and 443
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment