Reverse Proxy

Introduction

There are a couple of proxies that most of us are familiar with:

  • Forward Proxy (or) Proxy
  • Reverse Proxy

“Forward” and “Reverse” are seen in context to the client (User-agent) accessing the resource. Resources could be (not limited to):

  • Services that are typically a website (or) an endpoint
  • FTP servers

Why?

Let’s consider an example organization named QWERTY and that the infrastructure team has defined a policy like this:

  1. Anyone who is accessing the internet will have to adhere to the policies defined in the organization.
  2. Anyone who is accessing the service hosted in the infrastructure should not directly access the service endpoint.

What?

As an employee, how will you access the resources?

For scenario 1, you would need to know:

  • What are the policies or rules?
  • Are you allowed to access the internet? (Allow also implies your designation (or) your IP address (or) any other filter criteria)

This would be difficult for an individual (or) a program to keep track of every resource on the internet that can be accessed within an organization.

Instead, what if such things are defined in a server and you are allowed to remember only the server name and port number. That’s really cool stuff, right?

Forward proxy server does just that.

The proxy server acting on your behalf will forward your request to the intended endpoint/website.

It also denies serving the request if the resource does not meet the organization policy.

The configuration of forward proxies are inclined towards how the organization’s infrastructure team decides on the following parameters (not limited to):

  1. What can be forwarded to the websites/end-points?
  2. What should be blocked to the user agents?
  3. What is the bandwidth consumed when accessing the resources over the network?

Since this varies across the organization, let’s focus more on scenario 2.

You would need to know what the proxy server is that will act on behalf of the website/endpoint that serves your request. Partly, this is sufficient to know. However, let’s take an example:

You (or) your program wants to access an endpoint (Example: http://qwerty.com)

In this case, you know that the website has a domain name called qwerty.com and can be accessed via http protocol. However, that is totally abstracted from the end user.

The configuration of reverse proxies are inclined towards the architectural decisions on the following parameters (not limited to):

  1. What happens to my service if it gets spammed with millions of requests?
  2. What happens to my service if an attacker/hacker gets access to the servers?
  3. What happens to my service when an infrastructure update is required. This could be related to hardware (or) OS patches?
  4. What happens to consumers of my service when I want to change my service name from http://qwerty.com to http://asdfgf.com?
  5. What happens to my service when the dependant service is down?
  6. What happens when my service endpoints have to be accessed via https but cannot pay for “N” number of ssl certificates?

Questions like the above will drive a person to choose reverse proxy

How Do You Set up a Reverse Proxy?

Nginx

Check the below code snippet.

Open nginx.conf file (If you are attempting it for the first time, take a backup)

Under the location section, add the proxy pass setup with your server endpoints as below.

......
 server {
    listen <%= ENV["PORT"] %>;
    server_name    localhost;
    //Any context-path's with "/api" will be served by api-qwerty.com
    location /api {
        proxy_set_header       Host api-qwerty.com:80;
        proxy_set_header       X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass             http://api-qwerty.com;
    }
    
    //Any context-path's with "/ui" will be served by ui-qwerty.com
    location /ui {
        proxy_set_header       Host ui-qwerty.com:80;
        proxy_set_header       X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass             http://ui-qwerty.com;
    }
  }

Apache

Open your httpd.conf file. (If you are attempting it for the first time, take a backup)

You can add the below lines and replace the context path and endpoint as desired.

....
ProxyPass /api http://api-qwerty.com/api
ProxyPassReverse /api http://api-qwerty.com/api

ProxyPass /ui http://ui-qwerty.com/ui
ProxyPassReverse /api http://ui-qwerty.com/ui
....

Let me know your thoughts in the comments below.