Robin.te.Hofstee

Securing Nginx Web Server Against Attacks

Robin te Hofstee5 min readViews2
Securing Nginx Web Server Against Attacks

This tutorial provides step-by-step guidance to harden your Nginx server against common vulnerabilities. Follow these best practices to secure your de

Securing Nginx Web Server Against Attacks

This tutorial provides step-by-step guidance to harden your Nginx server against common vulnerabilities. Follow these best practices to secure your deployment.

Table of Contents

  1. Introduction
  2. Keep Nginx Updated
  3. Configure Firewall
  4. Disable Directory Listing
  5. Limit Server Metadata
  6. Enable HTTPS
  7. Enable Security Modules
  8. Restrict Access by IP
  9. Rate Limiting HTTP Requests
  10. Content Security Policy (CSP)
  11. Block Directory Traversal
  12. Monitor Logs with Fail2Ban
  13. Disable Unused Modules
  14. Additional Security Best Practices
  15. Summary

Introduction

Nginx is a high-performance web server, but security requires proactive configuration. This guide covers critical steps to mitigate risks like directory listing, brute-force attacks, and XSS vulnerabilities.

Update Nginx

Regularly update Nginx to patch vulnerabilities:

sudo apt update && sudo apt upgrade nginx  

Configure Firewall

Use ufw to restrict access to essential ports:

sudo ufw allow ssh  
sudo ufw allow http  
sudo ufw allow https  
sudo ufw enable  

Explanation:

  • SSH: Server management.
  • HTTP/HTTPS: Web traffic.

Disable Directory Listing

Prevent sensitive files/directories from being listed:

  1. Edit your Nginx config:
    sudo nano /etc/nginx/site-available/your_site  
  2. Add:
    autoindex off;      # Disable directory listing  
    directory_index off; # Disable default index file  
  3. Apply changes:
    sudo nginx -t && sudo systemctl reload nginx  

Limit Server Metadata

Hide Nginx version and headers:

  1. Edit the main configuration:
    sudo nano /etc/nginx/nginx.conf  
  2. Add:
    server_tokens off;                  # Hide Nginx version  
    server_name_in_redirect off;        # Avoid leaks in redirects  
    proxy_hide_header Server;           # Hide headers in proxied requests  
  3. Apply changes:
    sudo nginx -t && sudo systemctl reload nginx  

Enable HTTPS with Let’s Encrypt

Automate SSL certificate setup:

  1. Install Certbot:
    sudo apt install certbot python3-certbot-nginx  
  2. Generate a certificate:
    sudo certbot --nginx -d yourdomain.com  

Note: Certbot automatically configures redirects from http to https.

Enable Security Modules

Use built-in security features in Nginx:

Rate Limiting

Enable the limit_req module to throttle traffic:

sudo apt install nginx-extras  # Includes rate limiting  

Configure in your site config:

limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;  
 
location / {  
    limit_req zone=api_limit burst=20 nodelay;  
}  

Custom Headers

Add security headers to all responses:

add_header Content-Security-Policy "default-src 'self'; script-src 'none'";  
add_header X-Content-Type-Options nosniff;  
add_header X-Frame-Options DENY;  

IP Whitelisting

Restrict access to authorized IPs:

location /admin {  
    allow 192.168.1.100;  
    allow 10.0.0.0/8;  
    deny all;  
}  

Rate Limiting for Authentication

Protect login forms from brute-force attacks:

  1. Configure authentication:
    auth_request user_login;  
  2. Create /etc/nginx/locations/user_login:
    map $http_user_agent $bot_buster {  
        default 0;  
        "nginx" 1; # Block requests with UA containing "nginx"  
    }  
     
    location /login {  
        allow_always $bot_buster;  
        if ($bot_buster = 1) {  
            return 444;  
        }  
    }  

Content Security Policy (CSP)

Block cross-site scripting (XSS) by restricting script sources:

add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://trusted-cdn.com" always;  

Block Directory Traversal

Prevent malicious URL manipulation:

location / {  
    if ($request_uri ~* /\.\./) {  
        return 403;  
    }  
}  

Log Monitoring with Fail2Ban

Install Fail2Ban to auto-block IPs with repeated failed requests:

  1. Install Fail2Ban:
    sudo apt install fail2ban  
  2. Create /etc/fail2ban/jail.d/nginx.conf:
    [nginx-badbots]  
    enabled = true  
    port = http,https  
    filter = nginx-badbots  
    logpath = /var/log/nginx/access.log  
    maxretry = 3  
    findtime = 600  
    bantime = 86400  
  3. Restart Fail2Ban:
    sudo systemctl restart fail2ban  

Disable Unused Modules

Minimize server attack surface by disabling unused modules:

sudo systemctl stop nginx  
sudo nano /etc/nginx/nginx.conf  

Remove unnecessary load_module blocks and reload:

sudo systemctl start nginx  

Additional Security Best Practices

  1. Enable HSTS:
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;  
  2. Security Headers:
    add_header X-XSS-Protection "1; mode=block" always;  
  3. File Permissions: Restrict access to sensitive files (e.g., chmod 600 /etc/nginx/conf.d/ssl.conf).
  4. Backup Configs: Regularly back up /etc/nginx/ and SSL certificates.

Summary

By following these steps, you will harden your Nginx server against attacks:

  • Keep Nginx updated.
  • Use a firewall to limit exposed ports.
  • Disable directory listing and traverse vulnerabilities.
  • Enforce HTTPS with Let’s Encrypt.
  • Enable rate limiting and monitoring (Fail2Ban).
  • Hide server metadata and CSP headers.

Remember: Security is an ongoing process. Regularly audit your configurations!

Share this post
Robin te Hofstee

Written by Robin te Hofstee

Technology enthusiast with a deep love for programming. Sharing practical guides on React, Next.js, Linux and self-hosting.

How Git Works

1

Git is a distributed version control system that allows multiple people to collaborate on a project while maintaining a complete history of all change