Struggling with Apache Reserver Proxies and it's configuration?
A reverse proxy is a proxy that accepts HTTP(s) requests and forwards them to one or more back-end server.
Reverse proxies are beneficial as a lot of website process the incoming HTTP request with their web application server.
here is the problem..
..it can be directly accessed by the users as the connection behind the reverse proxy is direct.
It only supports basic HTTP features.
Although, you can prevent the user from directly accessing back-end servers behind the proxy by distributing the load among the servers along with setting up Failovers.
The reverse proxy can bring more features that are not given by the back-end servers such as caching mechanism, SSL encryption, and compression.
Here we will see Apache reverse proxy configuration step by step.
Apache reverse proxy Ubuntu
Let's see how to use Apache as a reverse proxy using the mod_proxy extension to forward the incoming request to the one or more backend servers which are connected to the same network. You can use the following Apache reverse proxy examples.
We are using the flask web framework backend server for the demonstration.
But, you can use any backend to work.
- Ubuntu 16.04 with sudo non-root user with a firewall.
- You should install Apache 2 on your server
Enabling Apache Modules
Apache has many modules, but all of them are not activated during the installation.
Let us enable a module which we are going to use in this tutorial.
The Module we require is mod_proxy along with its add-on modules. It supports multiple networks protocols.
Some of the Mod Proxy modules
mod_proxy: mod_proxy is the Apache module which redirects the connection to the back-end servers. It also acts as the gateway to receive and forward the request to the back-end server.
mod_proxy_http: it gives support to the HTTP connection.
mod_proxy_balancer and mod_lbmethod_byrequests: If you have multiple back-end servers, then this module is helpful.
To enable all the modules:
Use the following commands:
$ sudo a2enmod proxy $ sudo a2enmod proxy_http $ sudo a2enmod proxy_balancer $ sudo a2enmod lbmethod_byrequests
(Run all the above commands)..
It's the time to restart the apache to obtain the effect of changes we have made.
The Apache Proxy server is ready to act as a reverse proxy to accept and process the request.
In order to test the reverse proxies..
..we will create a two back-end server.
(If you already have the one, just skip and read the next step. )
Create Back-End Servers
The simple back-end servers are helpful to test whether the Proxy you created working properly.
Let us test with two servers through the proxy.
One server will reply with the text of "Hello world" and the second one will send a reply of "Howdy World."
==In the usual non-test setup, all the back-end server will return the same type of content. But here, we are using different content for each of them to test whether load balancing mechanism uses both servers.==
To build simple web application:
We are going to use the Flask which is a Python Micro framework and it does not require in-depth knowledge of Python.
A simple application only requires a few lines of codes :)
You have to update the package list using the following command
$ sudo apt-get update
Install the Python Package Manager Pip which is suggested.
$ sudo apt-get -y install python3-pip
you have to use the Pip to install the flask
$ sudo pip3 install flask
Now we have installed all the required elements. The next step is creating a file which will contain the code for the first server.
The file has to be created in the home directory of the current user.
$ nano ~/backend1.py
Look at the below code. Just copy and Paste it into the file then save it.
~/backend1.py from flask import Flask app = Flask(__name__) @app.route('/') def home(): return 'Hello world!'
Let us look how the above program works
from flask import Flask
app = Flask(name) : These lines starts the flask frame work.
home() : it will retrun a line ("Hello World)
@app.route('/') : this functions tells the Home function to return the value to the HTTP Request received.
To create the file for the second server, follow the comment which we used above for server 1.
$ cp ~/backend1.py ~/backend2.py
Open the file
$ nano ~/backend2.py
Use code that we used for server 1 file and just the replace the Hello World line with Howdy World.
The code should be like this
~/backend2.py from flask import Flask app = Flask(__name__) @app.route('/') def home(): return 'Howdy world!'
Now, you have to start the first background server and make it listen on port 8080. The output path of the Flask would be /dev/null.
$ FLASK_APP=~/backend1.py flask run --port=8080 >/dev/null 2>&1 &
We are setting up the FLASK_APP Environmental variable with the same flask command line
Creating Environment Variable is the suitable way to pass the information to process from the shell.
Here, the environment variable stays temporarily and can be used by that specified command line so that there will be no confliction when we start the second server.
Now, let us start the second server and make it list to port 8081. Here the value of the FLASKAPP() environment variable differs.
$ FLASK_APP=~/backend2.py flask run --port=8081 >/dev/null 2>&1 &
Now, we can check whether the servers are running properly using curl.
Test the first server
$ curl http://127.0.0.1:8080/
The output will be Hello World
Test the second server
$ curl http://127.0.0.1:8081/
The Output will be Howdy World
Note: Close the test servers you created once you finished the usage using killall flask.
After that, we are going to modify the Apache configuration to make it work as the reverse proxy.
Modify Default Configuration to Enable the Reverse Proxy
Here, our work is to use default apache virtual host and make it work like the reverse proxy for single backend server or list of load balanced backend server.
Note: we are using the Apache default virtual host to apply the configuration. But, you can also apply the same configuration to all other virtual hosts.
One more thing to note. If you are using Apache reverse proxy virtual host to accept both HTTP and HTTPS, you have applied the configuration to both virtual hosts.
First, open the default apache configuration file(000-default.conf) in nano or text editor
$ sudo nano /etc/apache2/sites-available/000-default.conf
In that file, you can find a line <VirtualHost *:80>. There are two examples we are going to show.
One will configure the Apache reverse proxy for a single server. The next one will configure the load balancer for multiple back-end servers.
Reverse Proxy for Single Server
Copy and paste the code into virtual host * 80 block.
/etc/apache2/sites-available/000-default.conf <VirtualHost *:80> ProxyPreserveHost On ProxyPass / http://127.0.0.1:8080/ ProxyPassReverse / http://127.0.0.1:8080/ </VirtualHost>
We have mentioned the IP address of the server that we have created, but you can use your web application server's IP address.
Let me explain the code we used above.
ProxyPreserveHost - This code makes the Apache virtual host pass the Host Header to the back-end server so that the back-end server can be aware of the address used to access the application
ProxyPass - This line tells the Apache to pass the request which is coming under root to the specified backend server address.
If you are trying to access the /example, then the apache server will forward the request http://backend_server/example and return the response to the client.
ProxyPassReverse - Both ProxyPassReverse and ProxyOass should have the same configuration. The ProxyPassReverse makes the Apache server to change the header from the back end server response.
If your back-end server returns the location redirect header, the client will get the proxy address not the back end server address.
Now restart the Apache to make the configuration work
$ sudo systemctl restart apache2
If you access the server with its IP address (http://ServerIpaddress), you can see the response from the backend server and the standard apache page won't be displayed.
If you follow the step two, you will see "Hello World."
Load Balancing for Multiple Server
If you are using more back-end server, then you can load balance all of them using load balancing functions in Apache.
Copy and paste the below code in your virtual host block
/etc/apache2/sites-available/000-default.conf <VirtualHost *:80> <Proxy balancer://mycluster> BalancerMember http://127.0.0.1:8080 BalancerMember http://127.0.0.1:8081 </Proxy> ProxyPreserveHost On ProxyPass / balancer://mycluster/ ProxyPassReverse / balancer://mycluster/ </VirtualHost>
The configuration is same for both single server and multiple servers. But there is a small difference in code.
Here, we are mentioning multiple back-end servers instead of using single backend server. We used the additional block balancer://mycluster to specify the multiple servers.
The Apache uses this load balancer pool to choose the server instead of directly accessing the server.
If you followed the steps, use server 1 and server 2 IP address and port. If you have the own application server, then use their IP address.
Once you finished the process, restart the Apache to see the effect.
$ sudo systemctl restart apache2
Now input the second server IP address and Port. You will get the response "Howdy World."
If you entered the server 1 IP address, you would get the response" Hello World."
If you get the above outputs, then it means the reverse proxy is working and load balancing between the servers.
P.S. Apache reverse proxy ssl provides the SSL for servers which are not supporting the SSL.
Now you have learned how to use Apache as the Reverse proxy for single and multiple backend servers. Also now you know how to load balance between multiple servers.
The mod_proxy can be used to configure the reverse proxy for web applications written in various languages such as Python, Ruby Rails and Django.
Apache also works as a load balancer to one or more back-end servers and provide the maximum availability of servers which have the high traffic.