Secure Nginx

How to secure a Nginx web server.

Steps you can take to secure your Nginx web server.

Disable unused Nginx modules

By default, Nginx comes with preinstalled modules that you may not need for your project. Disable unused Nginx modules in order to reduce the attack surface.

To disable unused Nginx modules, you need to recompile Nginx without the modules you don't need:

  1. Uninstall Nginx if it's already installed.

  2. Download the uncompiled Nginx version to build it from source.

  3. Run ./configure along with the modules you don't want to install. Here's an example:

     ./configure --without-http_map_module
     make
     make install

Disable server_tokens

server_tokens outputs the Nginx version in each HTTP response header.

Disable server_tokens by following these steps:

  1. Edit the nginx.conf file:

     vi /etc/nginx/nginx.conf
  2. Add the server_tokens parameter with the off value in the server { } block directive.

     server {
        listen 127.0.0.1:80;
        server_name mydomain.com;
        
        server_tokens off;
     }
  3. Restart Nginx:

     sudo systemctl restart nginx
  4. Verify that the header has been removed from the request response:

     curl -I https://www.mydomain.com/

Disable X-Powered-By

By default, a X-Powered-By header is added by Nginx to server requests.

Disable the X-Powered-By header on Nginx:

  1. Edit the nginx.conf file:

     vi /etc/nginx/nginx.conf
  2. Inside the server {} block directive use more_clear_headers:

     server {
        ....
        more_clear_headers "Server";
        more_clear_headers "X-Powered-By";
        ....
     }
  3. Restart Nginx:

     sudo systemctl restart nginx
  4. Verify that the header has been removed from the request response:

     curl -I https://www.mydomain.com/

If the more_clear_headers (More Clear Headers module) is not installed for your Nginx server and you're using PHP-FPM, try:

 location ~ \.php$ {
        fastcgi_hide_header         X-Powered-By;
    }

Disable unused HTTP methods

You can disable unused HTTP methods such as DELETE, TRACK, TRACE and keep only the common HTTP methods used: GET, POST, HEAD.

  1. Edit the nginx.conf file:

     vi /etc/nginx/nginx.conf
  2. Add the following directive in the server { } block directive:

     server {
        if ($request_method !~ ^(GET|HEAD|POST)$) {
            return 405;
        }
     
        # other lines
     }

    This code snippet will return HTTP error code 405 (Method Not Allowed) if the HTTP method is not GET, POST or HEAD.

  3. Restart Nginx:

     sudo systemctl restart nginx

Use TLS

You can use TLS instead of SSLv3 to prevent unwanted attacks on your Nginx server.

Use the ssl_protocols TLSv1.3; in the nginx.conf file:

  1. Edit the nginx.conf file:

     vi /etc/nginx/nginx.conf
  2. Go to the server {} block directive:

     server {
        ....
        ssl_protocols TLSv1.3;
        ....
     }
  3. Restart Nginx:

     sudo systemctl restart nginx