Avatar
|
February 5, 2019
|

Build a Node.JS HTTP Proxy Server in Under 10 minutes

What are we going to build?

Today we are going to talk about how to build a complex proxy server which can serve both HTTP and https requests from Nodejs. It will be able to block certain URLs from accessing. I will increase the complexity gradually so, I can accommodate readers from different expertise levels. Even if you are a beginner in Nodejs you will find this tutorial very easy to understand. If you are an intermediate you won’t find it boring. This is written particularly for deploying a Nodejs proxy on a Ubuntu VPS that can be used to configure a Firefox browser. But the process is very same for other scenarios as well.

Let’s start by installing Nodejs. There are several ways you can install Nodejs. I will use the most convenient method here.

Installing Node.js

Update your apt tool with the following command

sudo apt update

We need curl to get the node packages. So, let’s install it first.

sudo apt install curl

Let’s download node packages with curl.

curl -sL https://deb.nodesource.com/setup_10.x | sudo bash -

It’s time to install node.js now

sudo apt install nodejs

Finally, verify if node.js is successfully installed before we move ahead.

node -v

If you are getting the version correctly, that means you are good to go.

Creating a Basic proxy

Creating a proxy server in Nodejs is as easy it can be. Open your favorite text editor and copy the code below and save it as proxy.js. Note that, we only send a simple text here. Because our intention is to check whether our requests are proxied properly.

var http = require('http');

var proxy = require('http-proxy');

proxyServer= proxy.createProxyServer({target:'http://127.0.0.1:9000'});

proxyServer.listen(8000);

server = http.createServer(function (req, res) {

  res.writeHead(200, { 'Content-Type': 'text/plain' });

  res.write('Proxy Request was Successful!' + '\n' + JSON.stringify(req.headers, true, 2));

  res.end();

});

server.listen(9000);

Use the following command to run the file.

node proxy.js

This is all it takes to create a working proxy server. To use the proxy server with your browser, you have to configure it. Open your Firefox browser and go to options from the menu on the right side you can find network settings under the general tab at the bottom of the page.

Next, go to network settings.

Probably you already have a good grasp of these settings. We can configure our newly created proxy server under manual configuration. Note that, our proxy can only serve HTTP requests.

Insert the values as I have shown in the below image.

It’s time to test our proxy server. Type any HTTP URL in the browser. I will go to http://www.espncricinfo.com.

Cool, we get the response we want. Now, getting this response will not be that useful unless for initial testing purposes. Its time to deliver client what he wants, the website content he requests. For that, we will modify our code like below.

var http = require('http');

var proxy = require('http-proxy');

var url = require('url');

proxyServer = proxy.createProxyServer({target:'http://127.0.0.1:9000'});

proxyServer.listen(8000);

server = http.createServer(function (req, res) {

 console.log(req.url);

 proxyServer.web(req, res, { target: req.url });

 proxyServer.on('error', function(e) {

  console.log("Error in proxy call");

 });

});

server.listen(9000);

Okay, run your script again. Open your browser and type http://espncricifno.com

Great. this time we get What we want. We can see the content of the website.

Block URLs.

If you are developing a proxy server for your employees to use, you definitely don’t want them to waste their time on Facebook. There could be many reasons why you want to block users from accessing certain URLs. Sometimes you don’t want to give permissions to view inappropriate sites from your proxy server. You probably won’t like to let people visit Websites with security problems, illegal websites with your proxy server. With Nodejs, you can achieve this with just a few more lines.

We will create a file called blocked.txt and add the URLs that you want to block. Next, we create our proxy server with custom logic to prevent them from being accessed.

Add the following code to your proxy server.

var blocked = [];

fs.watchFile('./blocked.txt', function(c,p) { update_blocked_list(); });

function update_blocked_list() {

  sys.log("Updating blocked files.");

  blocked = fs.readFileSync('./blocked.txt').split('\n')

              .filter(function(rx) { return rx.length })

              .map(function(rx) { return RegExp(rx) });

}

http.createServer(function(request, response) {

  for (i in blocked) {

    if (blocked[i].test(request.url)) {

      sys.log("Denied: " + request.method + " " + request.url);

      response.end();

      return;

    }

  }

}

Add http://facebook.com to your file. Run the file, and go to  http://facebook.com from your browser.

Great, we get access denied message. Now, no one will be able to access Facebook

from your proxy server.

Enable HTTPS in our proxy server

Are you happy with what you have done so far? But there is a thing. There is still a big problem with our server. Even though your clients won’t be able to go to http://facebook.com your clients can go to https://www.facebook.com. But, that’s not the worst case. Try accessing google.com. Do you see that you can’t access http://www.google.com. Because Google does not have an HTTP website. It’s nearly useless to have an HTTP only proxy in the current internet. So, why stop there. Let’s implement our server to server https requests as well.

var fs = require('fs');

var http = require('http'),

var https = require('https'),

var httpProxy = require('http-proxy');

isHttps = true;

var options = {

  ssl: {

    key: fs.readFileSync('valid-key.pem'),

    cert: fs.readFileSync('valid-cert.pem')

  }

};

proxyServer = proxy.createProxyServer({target:'http://127.0.0.1:9000'});

proxyServer.listen(8000);

if (isHttps){

   server = https.createServer(options.ssl, function(req, res) {

     console.log(“https request”);

     proxyServer.web(req, res, { target: req.url });

     proxyServer.on('error', function(e) {

  console.log("Error in proxy call");

     });

     proxyServer.listen(443);

   });

}else{

  server = http.createServer(function (req, res) {

  console.log(req.url);

  proxyServer.web(req, res, { target: req.url });

  proxyServer.on('error', function(e) {

   console.log("Error in proxy call");

  });

    });

 }

 server.listen(9000);

Now, configure your web browser to accept https request. Tick on the box ‘use this proxy server for all requests’ in the network configuration page.

 

That’s it. Try accessing google.com again. This time you will be successful. You can try other functionalities as well. Node.js provides you with a great framework for your works. So,  it is time to enjoy your newly built proxy server.

COMMENTS (2)

  • Avatar

    nobodyshomeSeptember 5, 2019 1:49 pm

    Reply

    In your last block of code you have 3 ports mentioned (443, 8000 and 9000). What one is supposed to be used?

  • Avatar

    newadminSeptember 15, 2019 1:18 am

    Reply

    I can see why this is confusing, we will rewrite this and update you once the new tutorial is ready. Thanks for your feedback.

LEAVE A COMMENT