NGINX: Improving Security for Reverse Proxies

Qualys SSL Labs report for my domain showing an A+ rating after making the necessary security changes to my NGINX reverse proxy server.

The following are my notes on improving the security of my NGINX reverse proxy installation. I realized I needed a security upgrade after running Securi Sitecheck and the Qualys SSL Server Test.

I wanted to secure the reverse proxy server as much as possible, mostly so that I wouldn’t need to make too many changes on each of the servers it redirects to. For details on how I installed and configured NGINX as a reverse proxy in the first place, see this post.

Update to the latest stable nginx

Check the current server version with the following terminal command:

nginx -v

If you need to update, backup the current installation folder, just in case:

sudo cp -r /etc/nginx /etc/nginx.backup

Then, add the stable NGINX repository and update the system:

sudo add-apt-repository ppa:nginx/stable
sudo apt-get update

Finlly, install the most recent supported software version:

sudo apt-get install nginx

Create an ip “whitelist” include file for private proxies

Create a new file in /etc/nginx called “whitelist” and add the following:

allow (insert allowed ip address here);
allow (insert allowed ip address here);
allow (insert allowed ip address here);
deny all
error_page 403 /403.html;
location/403.html {
     root /504.html;
     allow all;

Include the whitelist in the server block in the site definitions of “private” proxies so they aren’t available except to you (things like esxi, ilo, etc.). For example:

server {
     include /etc/nginx/whitelist;
     listen ...;
     server_name ...;
     location / {
         proxy_pass ...;

This way, servers you want to be public are public, while private servers can only be accessed from your whitelisted IP addresses.

Generate a dhparam.pem

Make sure to haveged installed and running prior to generating dhparam.pem (otherwise it would take a long time):

sudo apt-get update;
sudo apt-get install haveged;

Then run in terminal:

openssl dhparam -out /etc/nginx/dhparam.pem 4096

Configure More Secure SSL for NGINX

Add the following to the http block of nginx.conf:

ssl_session_cache shared:le_nginx_SSL:1m;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 5m;
ssl_buffer_size 1400;
ssl_ecdh_curve secp521r1:secp384r1:prime256v1;
ssl_session_tickets off;

ssl_dhparam /etc/nginx/dhparam.pem;

ssl_protocols TLSv1.2 TLSv1.3;

ssl_prefer_server_ciphers on;
ssl_ciphers AES256+EECDH:AES256+EDH:!aNULL;

resolver [2606:4700:4700::1111 [2606:4700:4700::1001];
resolver_timeout 5s;
ssl_stapling on;
ssl_stapling_verify on;

add_header Strict-Transport-Security"'max-age=31536000; includeSubDomains; preload; always";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
# add_header X-Robots-Tag none; # Didn't add to nginx.conf file

Once these changes are made, test the configuration and reload the server:

sudo nginx -t
sudo service nginx reload

Block Unwanted Headers from Proxied Servers

Since NGINX is the gateway to the other servers, you can remove headers from responses created by the proxied machines before any packets leave the local network.

For example, this is can be used to always block servers from leaking PHP versions by adding the following to the HTTP block of nginx.conf:

proxy_hide_header X-Powered-By;

The same approach can also block server banners from leaking:

proxy_hide_header Server;

Although adding the following is a good idea to stop the proxy server itself from broadcasting its identity:

server_tokens off;

Once any changes are made, test the configuration and reload the server:

sudo nginx -t
sudo service nginx reload

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.