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.

FAQ

Is Nginx Security Hardening important for Ubuntu administrators?+

Yes. It supports practical Ubuntu administration because it connects directly to server reliability, security, troubleshooting, or daily operations.

Should I practice this on a live server?+

Use a lab VM first. After you understand the command output and rollback path, apply the workflow carefully on real systems.

What should I do after reading this article?+

Run the practice commands, write down what each one shows, and continue to the next article in the Ubuntu roadmap.

Need help with Ubuntu administration?

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

Hire Me for Support