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