Node.js - Programmatically Connect to a VPN or route HTTP Requests via VPN

Sunday Ironfoot picture Sunday Ironfoot · Aug 17, 2015 · Viewed 13.7k times · Source

This is probably a bit of a long shot. But in Node.js I want to make an HTTP request (using, for instance, the request package on npm) via a VPN server. I already have a VPN server set-up (using HideMyAss) and I can connect to it at the Operating System level, by configuring it in my OSs networking settings section. But I want to connect to it programmatically using a Nodejs program, and have any HTTP requests made using that program routed through that VPN.

This can be done using proxies, for instance:

var request = require('request');

var url = 'https://www.google.com';
var proxy = 'http://username:[email protected]:1234';

request.get({ url: url, proxy: proxy }, function(err, res, body) {

});

...but I want to do something similar with VPNs. Is this even possible? Thanks!

Answer

Yan Foto picture Yan Foto · Aug 17, 2015

VPNs (normally) tunnel layer 2 or 3 network packets through a specific channel. From the perspective of application layer, you don't have to take care of lower levels, as routing the network packages is taken care by the OS. OpenVPN for example creates a TUN or TAP virtual interface and channels all packets send by OS to these interfaces through a secure tunnel. The decision which interface to use is done regarding the routing table. A web proxy server is much simpler than a VPN since it just accept HTTP requests (application layer) and relays them.

It really depends on what kind of VPN you are using. Lets say that you're using OpenVPN and it creates a virtual interface for you (e.g. tun0), this interface has its own IP address (e.g. 10.124.1.6) and maybe (depending on the server's topology) a P2P address (e.g. 10.124.1.5). You could instruct Node to bind the network connections through a specific (local) network interface using the localAdress:

var options = {
  host: "example.com",
  path: "/path/to/web/service",
  localAddress: '10.124.1.6', // IP address network interface
};
http.request(options);

Hypothetically, this would be the solution of selectively tunneling specific requests through a VPN interface. If this works or not, I cannot guarantee. But I'd say it would get you started with some ideas.