How to setup a reverse proxy on Ubuntu 20.04
By: Satria Janaka
Tags: Apache, Computer Networking

A reverse proxy is a type of proxy server that retrieves resource behalf on behalf a client from one or more servers. These resource are then returned to the client, appearing as if they originated from the reverse proxy itself.

Example scenario : A client on the internet (cloud on the left) makes a request to a reverse proxy server (red oval in the middle). The proxy inspects the request, determines that it is valid and that it does not have requested resource in its own cache. It then forwards the request to some internal web server (oval on the right). The internal server delivers the requested resource back to the proxy, which in turn delivers it to the client. The client on the internet is unaware of the internal network, and cannot tell whether it is communicating with a proxy or directly with a web server.

Reverse proxy servers are implemented in popular open-source web servers such as Apache, Nginx, and Caddy. For this tutorial, we will learn how to setup a reverse proxy with Apache in Ubuntu 20.04

What you need is Ubuntu 20.04 installed in your machine (of course!) with Apache installed.

Install Apache web server

Run these command in your terminal :

$ sudo apt update

$ sudo apt install apache2

After the installation finished, you can check the status of Apache web server by running this command :

$ sudo systemctl status apache2

If the status prompt show status active (running) , then it means the Apache web server has been setup and started.

Dependencies

We will use a tool called Flask, a micro-framework written in Phyton used for the development of web applications. Open a terminal window and install Flask with following commands :

$ sudo apt-get update

$ sudo apt-get -y install python3-pip

$ sudo pip3 install flask

Next, we need to enable some Apache modules. To do this, issue the following commands:

$ sudo a2enmod proxy

$ sudo a2enmod proxy_http

$ sudo a2enmod proxy_balancer

$ sudo a2enmod lbmethod_byrequests

After install the dependencies, next step is restart the Apache web server with this following command :

$ sudo systemctl restart apache2

Create backend services

To test our Apache reverse proxy later, we need to create two backend services. We’re going to make the backend services with a bare minimum of configurations and options. Create the configuration file for first backend services, named backend-server-1.py with your favourite text editor. In backend-server-1.py file, copy the following content :

Save and close that file. Next, let’s create the configuration file for the second backend services, named backend-server-2.py . In that file, copy the following content :

Save and close that file.

Serve and Test our backend services

Use Flask tool to start the first background server on port 8080 and redirect the output to /dev/null. Run this following command in your terminal to serve the first backend on port 8080 with Flask :

$ export FLASK_APP=backend-server-1.py

$ flask run --host 127.0.0.1 --port 8080

Open a new terminal window, then run this following command to serve the second backend on the default port, which is 5000 :

$ export FLASK_APP=backend-server-2.py

$ flask run

Next, test both the two backend services with this following command :

# test first backend

$ curl http://127.0.0.1:8080

This is Backend 1 # test second backend

$ curl http://127.0.0.1:5000

This is Backend 2

Great. Now the both backends are running.

Configure Apache

At this point, you can reach those backend servers only from localhost address ( 127.0.0.1 ). If you need to access the reverse proxy from your LAN, you need to reconfigure Apache. Before you do this, make a copy of your current Apache configuration file with this following command :

$ sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/000-default.conf.bak

Next, edit /etc/apache2/sites-available/000-default.conf file with your favourite text editor, replace the entire contents with this following :

These are three directives here :

ProxyPreserveHost makes Apache pass the original Host header to the backend server. This is useful, as it makes the backend server aware of the address used to access the application. ProxyPass is the main proxy configuration directive. In this case, it specifies that everything under the root URL ( / ) should be mapped to the backend server at the given address. For example, if Apache gets a request for /example , it will connect to http://your-backend-server/example and return the response to the original client. ProxyPassReverse should have the same configuration as ProxyPass. It tells Apache to modify the the response headers from backend server. This makes sure that if the backend server returns a location redirect header, the client’s browser will be redirected to the proxy address and not the backend server address, which would not work as intended.

To apply our changes, restart the Apache web server :

$ sudo systemctl restart apache2

Now, if you access http://your-server-ip in a web browser, you will see backend server response instead of standard Apache welcome page. Which is, This is Backend 1

Now, let’s try it once more. The goal is to make if we access http://your-server-ip , we will get This is Backend 2 as response. Edit etc/apache2/sites-available/000-default.conf file and replace the content with following :

Now, restart the Apache web server :

$ sudo systemctl restart apache2

Now, let’s try to access http://your-server-ip in a web browser

You should get This is Backend 2 as the response. That means our Apache reverse proxy has been setup correctly.