Setting up an Nginx Reverse Proxy

What Is a Reverse Proxy?

A reverse proxy is an intermediary proxy service which takes a client request, passes it on to one or more servers, and subsequently delivers the server’s response to the client. A common reverse proxy configuring is to put Nginx in front of an Apache webserver. Using this method will allow both web servers to work together enabling each to do what they do best

What is Nginx?

NGINX is open source software for web serving, reverse proxying, caching, load balancing, media streaming, and more. It started out as a web server designed for maximum performance and stability. In addition to its HTTP server capabilities, NGINX can also function as a proxy server for email (IMAP, POP3, and SMTP) and a reverse proxy and load balancer for HTTP, TCP, and UDP servers.

Benefits of an Nginx Reverse Proxy

There are a few benefits to setting up an Nginx reverse proxy. Although not required in all cases, it can be beneficial depending upon your particular scenario/setup. The following outlines a few benefits implementing a reverse proxy.

  • Better Performance –
    • Nginx has been known to perform better in delivering static content over Apache. Therefore with an Nginx reverse proxy, all client requests can be handled by Nginx while all requests for dynamic content can be passed on to the backend Apache server. This helps improve performance
  • Load Balancing –
    • A reverse proxy can perform load balancing which helps distribute client requests evenly across backend servers. It helps to avoid the scenario where a particular server becomes overloaded due to a sudden spike in requests. Load balancing also improves redundancy as if one server goes down, the reverse proxy will simply reroute requests to a different server. Read our complete article to learn more about load balancing.
  • Increased Security –
    • A reverse proxy also acts as a line of defence for your backend servers. Configuring a reverse proxy ensures that the identity of your backend servers remains unknown. This can help in protecting your servers from attacks such as DDoS for example.
  • Easy Logging and Auditing –
    • Since there is only one single point of access when a reverse proxy is implemented, this makes logging and auditing much simpler. Using this method, you can easily monitor what goes in and out through the reverse proxy.

Environment Setup & Preliminary Note

In this tutorial, I used the IP address 10.0.50.57 as the host system. These settings might differ for you, so you have to replace them where appropriate. I’m using Ubuntu 18.04 Lts for the entire setup.

 

#Step 1: Install Apache

Apache is available within Ubuntu’s default software repositories, so we will install it using conventional package management tools.

We will begin by updating the local package index to reflect the latest upstream changes. Afterwards, we can install the apache2 package:

sudo apt update

sudo apt install apache2

After confirming the installation, apt will install Apache and all required dependencies.

If all are ok then go to web browser and type your host IP (In My Case 10.0.50.57) it will serve default Apache server page like above image.

#Step 2: Configuring Apache

The first thing we have to do is configure our Apache vhost to listen on localhost (127.0.0.1) on an unused port other than 80 (e.g. 8080). Open /etc/apache2/ports.conf

sudo nano /etc/apache2/ports.conf

… and modify the NameVirtualHost and Listen lines for port 80 to use port 8080:

# If you just change the port or add more ports here, you will likely also
 # have to change the VirtualHost statement in
 # /etc/apache2/sites-enabled/000-default.conf
 
 Listen 8080
 
 <IfModule ssl_module>
  Listen 443
 </IfModule>
 
 <IfModule mod_gnutls.c>
  Listen 443
 </IfModule>

Next open the vhost configuration file (e.g. /etc/apache2/sites-available/000-default.conf)…

nano /etc/apache2/sites-available/000-default.conf

… and change the <VirtualHost> line to use the IP address 127.0.0.1 and the port 8080:

<VirtualHost 127.0.0.1:8080>[...]

We will configure Nginx as a transparent proxy, i.e., it will pass on the original user’s IP address in a field called X-Forwarded-For to the backend Apache. Of course, the backend Apache should log the original user’s IP address in their access logs instead of the IP address of Nginx (127.0.0.1). There are two ways to achieve this:

1) We can modify the LogFormat line in /etc/apache2/apache2.conf and replace %h with %{X-Forwarded-For}i:

sudo nano /etc/apache2/apache2.conf
[...]#LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combinedLogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined[...]

2) On Debian/Ubuntu, we can install the Apache module libapache2-mod-rpaf which takes care of logging the correct IP address:

sudo apt install libapache2-mod-rpaf

After all these changes, restart Apache:

sudo service apache2 restart

 

#Step 3: Configuring Nginx

If Nginx isn’t already installed, install it as follows:

sudo apt install nginx

Create its system startup links and make sure it is started:

sudo systemctl enable nginx.service
sudo service nginx restart

It should now be listening on port 80.

Some standard proxy parameters are in the file /etc/nginx/proxy_params:

sudo nano /etc/nginx/proxy_params
proxy_set_header Host $http_host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header X-Forwarded-Proto $scheme;

As we will include that file later on in the proxy part of our nginx vhost for example.com, you might want to add further proxy directives to that file if you like, e.g. as follows:

 proxy_set_header Host $http_host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header X-Forwarded-Proto $scheme; 
 
 client_max_body_size 100M;
 client_body_buffer_size 1m;
 proxy_intercept_errors on;
 proxy_buffering on;
 proxy_buffer_size 128k;
 proxy_buffers 256 16k;
 proxy_busy_buffers_size 256k;
 proxy_temp_file_write_size 256k;
 proxy_max_temp_file_size 0;
 proxy_read_timeout 300;

Now modify the default vhost for Nginx – make sure it uses the same document root as the Apache vhost for example.com (e.g. /var/www/html) so that Nginx can deliver static files directly without passing the request to Apache:

sudo nano /etc/nginx/sites-available/default
server {
      listen 80 default_server;
      listen [::]:80 default_server;
 
      root /var/www/html;
 
      # Add index.php to the list if you are using PHP
      index index.html index.htm index.nginx-debian.html;
 
      server_name _;
 
      location / {
        proxy_pass http://localhost:8080;
        include /etc/nginx/proxy_params;
      }
 }

This is a very simple configuration which would proxy all requests to Apache.

Reload Nginx for the changes to take effect:

sudo service nginx reload

Finally, we will test the Nginx configuration and restart Nginx:

sudo nginx -t
sudo systemctl restart nginx

You can now type the server hostname or the IP 10.0.50.57 into your browser, and you should see the apache default web site, but this time delivered through Nginx.

The same default apache server page loads but this time through Nginx.

Also, you can test it with curl:

curl -I 10.0.50.57

#Video Demonstration

#Conclusion

Nginx is fast and popular web server with low memory usage that can act as web server and reverse proxy for HTTP and HTTPS protocol. Nginx reverse proxy for apache is a setup that uses Nginx as front end, and apache as back end.


 

The following two tabs change content below.

Subroto Mondal

Chief Coordinator HR&CR
I like Programming and New Technologies. And work with Linux.

Latest posts by Subroto Mondal (see all)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.