In this tutorial, we will go through:
- Install and configure NGINX,
- Install and configure SSL/TLS,
- Configure NGINX as a reverse proxy for:
- A whole site,
- A directory of a site.
Requirements:
sudo apt update && sudo apt upgrade -y sudo apt install nginx -y sudo nano /etc/nginx/sites-available/default
Change the following configuration with your domain:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
server_name example.com www.example.com;
}
Check the configuration and restart the server.
nginx -t && nginx -s reload
Access your website using your web browser and note that is labeled as an insecure connection.
SSL/TLS
Install the Cerbot and execute it against your :
sudo apt-get install certbot python3-certbot-nginx -y sudo certbot --nginx
Only on the first time it will ass that many questions.
Alternatively, the domain could be specified to skip one step.
sudo certbot --nginx -d example.com -d example2.com
Reload the server and refresh the browser to verify that it was automatically redirected to a secure connection.
nginx -s reload
The browser will hop from HTTP://example.com to HTTPS://example.com.
Create a cron job using the root user to automatically renew the certificate that will expire every 90 days:
sudo su crontab -e
Append:
0 12 * * * /usr/bin/certbot renew --quiet
REVERSE PROXY
To prevent CPU overload with multiple encrypted sessions it is recommended to use regular HTTP connection internally when possible (restricted VLAN for example).
Edit the virtual server configuration:
sudo nano /etc/nginx/sites-available/default
Applying the reverse proxy to the root of the website.
Edit the virtual server configuration:
sudo nano /etc/nginx/sites-available/default
Look for the location { … } block.
location / { proxy_pass http://127.0.0.1:5000; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
This configuration will forward the traffic to the host and port defined. The example above will forward to localhost under port 5000, which could be a docker application listening on this port.
All the lines in orange are optional and will provide metadata to the hidden application if necessary.
Applying the reverse proxy to a directory of the website.
Create a location block to the desired directory.
location /proxied_page/ {
proxy_pass http://192.168.1.7;
}
In the example above the reverse proxy is applied only to the directory proxied_page to another host (192.168.1.7) in the private network on the default HTTP port.
BONUS: Reverse Proxy with Apache
sudo a2enmod proxy sudo a2enmod proxy_http sudo a2enmod proxy_balancer sudo a2enmod lbmethod_byrequests
Include the following lines accordingly to your need in the site configuration file:
ProxyPreserveHost On ProxyPass / http://10.1.1.1:8080/ ProxyPass /directory http://192.168.1.1/ ProxyPass /another_directory http://172.16.1.1/dir/
Restart the service.
sudo apachectl configtest sudo systemctl restart apache2.service
Additionally, the reverse proxy can also act as a load balancer:
<Proxy balancer://cluster> BalancerMember http://webserver1 BalancerMember http://webserver2 </Proxy> ProxyPreserveHost On ProxyPass / balancer://cluster/ ProxyPassReverse / balancer://cluster/
You can also apply health checks to the nodes of the members of the cluster:
<Proxy balancer://cluster> BalancerMember "http://webserver1" hcmethod=HEAD hcinterval=1 hcpasses=9 hcuri=/app/status BalancerMember "http://webserver2" hcmethod=HEAD hcinterval=1 hcpasses=9 hcuri=/app/status </Proxy>
Moreover, on the host side (where the web application is running) if it is running Apache too:
- The logs will contain the Remore Address IP of the reverse proxy server for all clients.
- To fix this issue the module mod_remoteip must be enabled and configured as follows.
sudo a2enmod remoteip sudo nano /etc/apache2/apache2.conf
Append the line:
RemoteIPHeader X-Forwarded-For
Change the following line.
From:
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
To:
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
Then, check the configuration and apply the changes:
sudo apachectl configtest && sudo systemctl restart apache2