I'm trying to implement a TCP proxy in Node JS. I only have some experience with Javascript so I met a lot of problems along the way. I've done a lot of searching for this one but had no luck.
I want to implement a two-hop TCP connection for HTTPS proxy. Here is part of my code.
var net = require('net');
var server = net.createServer(function(clientSock) {
var connected = false;
var serverSock;
clientSock.on('data', function(clientData) {
if (connected) {
// Send future messages if is connected
serverSocet.write(clientData);
} else {
var host = // get from data
var port = // get from data
if (clientData is a CONNECT request) {
// Create a new socket to server
if (!serverSock) {
serverSock = new net.Socket();
serverSock.connect(port, host, function() {
// Send the CONNECT request (Client Hello)
serverSock.write(clientData);
connected = true;
clientSock.write('HTTP/1.1 200 OK\r\n');
});
serverSock.on('data', function(serverData) {
clientSock.write(serverData);
});
}
}
});
});
I used Wireshark to capture the packets sent if I visit https://www.google.com. If I don't use my proxy, the "Client Hello" message is sent in TLS v1.2. But if I use my proxy, it is sent by SSL. The server always reject my CONNECT request and send back a reset request.
I also tried the TLS API in Node JS. The server accepted my CONNECT request but always request me to start a new session after the Key Exchange. The browser will close the socket and create a new socket. But it never loaded the page...
I've spent a whole day on this single problem. I believe I can use TCP socket to implement HTTP Tunnel. Please help... Thanks a lot!!
Problem solved!
To make TCP socket use TLS v1.2 while dealing with HTTPS, just put this option, {allowHalfOpen: true}, as parameter when creating the sockets.
New Code would look like this:
var net = require('net');
// option here
var server = net.createServer({allowHalfOpen: true}, function(clientSock) {
var connected = false;
var serverSock;
clientSock.on('data', function(clientData) {
if (connected) {
// Send future messages if is connected
serverSocet.write(clientData);
} else {
var host = // get from data
var port = // get from data
if (clientData is a CONNECT request) {
// Create a new socket to server
if (!serverSock) {
// Option here
serverSock = new net.Socket({allowHalfOpen: true});
serverSock.connect(port, host, function() {
// Don't need to forward hello message from client
// Connect method automatically sends it for you
//serverSock.write(clientData);
connected = true;
clientSock.write('HTTP/1.1 200 OK\r\n');
});
serverSock.on('data', function(serverData) {
clientSock.write(serverData);
});
}
}
});