Nginx Security Hardening

The default Nginx installation is functional but not hardened. The version number is advertised in response headers (giving attackers a target), SSL is configured with weak defaults, there is no rate limiting against brute force attacks, and security headers like Content-Security-Policy are absent. Hardening Nginx is a 30-minute task that significantly reduces the attack surface for your web applications.

Hiding server information

# In /etc/nginx/nginx.conf, inside the http block:
sudo nano /etc/nginx/nginx.conf

Security settings in nginx.conf http block

http {
    server_tokens off;                 # Hide nginx version in Server header and error pages
    more_clear_headers Server;         # Remove Server header entirely (requires nginx-extras)

    # Prevent nginx from revealing web root paths in error messages:
    # (default off, but explicit is clearer)
}
# Verify version is hidden:
curl -I https://yourdomain.com | grep -i server
# Should show: Server: nginx    (no version number)

SSL/TLS hardening

# Create a strong SSL configuration snippet:
sudo nano /etc/nginx/snippets/ssl-hardened.conf

/etc/nginx/snippets/ssl-hardened.conf

# Only TLS 1.2 and 1.3 — disable old protocols
ssl_protocols TLSv1.2 TLSv1.3;

# Strong cipher suites
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

# OCSP stapling (speeds up SSL handshake by caching cert revocation status)
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;

# Session caching
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
# Include in your server blocks:
# include snippets/ssl-hardened.conf;

# Check SSL configuration at: https://www.ssllabs.com/ssltest/

Rate limiting

# Define rate limit zones in http block (nginx.conf):
# limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
# limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;

# Apply in location blocks:
location / {
    limit_req zone=general burst=20 nodelay;
    # burst=20: allow up to 20 queued requests above rate limit
    # nodelay: don't delay burst requests, reject immediately when burst exceeded
}

location /login {
    limit_req zone=login burst=5 nodelay;
    # login endpoint: max 1 req/sec, allow burst of 5
}

Security headers

# Add to your server block or globally in http block:
add_header X-Frame-Options "SAMEORIGIN" always;           # Prevent clickjacking
add_header X-Content-Type-Options "nosniff" always;       # Prevent MIME sniffing
add_header X-XSS-Protection "1; mode=block" always;       # XSS filter (older browsers)
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# HSTS: tells browsers to always use HTTPS for 2 years

# Check headers:
curl -I https://yourdomain.com | grep -E "X-Frame|X-Content|Strict-Transport"

Blocking bad requests

# Block common attack patterns:

# Block requests for sensitive files (put in server block):
location ~* "(\.env|\.git|\.htaccess|\.htpasswd|config\.php|wp-config\.php)" {
    deny all;
    return 404;
}

# Block user agents of common scanners:
if ($http_user_agent ~* "(sqlmap|nikto|dirbuster|masscan)") {
    return 403;
}

# Return 444 (Nginx no-response) for requests with no Host header (scanner behavior):
server {
    listen 80 default_server;
    server_name _;
    return 444;   # Close connection without sending a response
}

Conclusion

The minimum hardening checklist for any internet-facing Nginx: server_tokens off, TLS 1.2/1.3 only with strong ciphers, rate limiting on all endpoints especially login forms, HSTS header, and block requests for .env/.git/config files. Run your domain through SSL Labs (ssllabs.com/ssltest) to verify your TLS configuration — it checks for known weaknesses and gives a grade. A well-hardened Nginx can score A+ consistently.

Need help with Ubuntu administration?

Work directly with Muhammad Irfan Aslam for Ubuntu Server, Linux, cloud, Docker, DevOps, CI/CD, or infrastructure troubleshooting support.

Work with Muhammad Irfan Aslam