NGINX Hardening Checklist 2025

A comprehensive security checklist for production NGINX servers. 40+ configurations covering version disclosure, TLS, headers, access control, and more.

Updated: January 2025 15 min read

1. Information Disclosure

Prevent attackers from fingerprinting your server.

Hide NGINX version Critical

Prevents attackers from targeting version-specific vulnerabilities.

# In http block
server_tokens off;

Remove Server header entirely Recommended

Requires the headers-more module or NGINX Plus.

# With headers-more-nginx-module
more_clear_headers Server;

Disable autoindex Important

Prevents directory listing that could expose sensitive files.

autoindex off;

2. TLS/SSL Configuration

Modern TLS settings for maximum security.

Use TLS 1.2 and 1.3 only Critical

TLS 1.0 and 1.1 have known vulnerabilities and are deprecated.

ssl_protocols TLSv1.2 TLSv1.3;

Configure modern cipher suites Critical

Use strong ciphers and prefer server's cipher order.

ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;  # Let client choose for TLS 1.3

Enable OCSP stapling — but not for Let's Encrypt Important

Stapling improves TLS handshake performance and privacy, but only when the certificate actually carries an OCSP URL. Let's Encrypt shut its OCSP responders down on 2025-08-06, so for a certbot certificate these directives are dead config — leave them out. Where stapling still applies, use a local resolver: an external one is a DNS-poisoning risk that Gixy rates HIGH. See the SSL/TLS guide.

# Commercial CA that still runs an OCSP responder
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/ssl/certs/example.com.chain.pem;
resolver 127.0.0.1 valid=300s;
resolver_timeout 5s;

Configure session caching Recommended

Improves performance for returning visitors.

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;  # Disable for forward secrecy

3. Security Headers

HTTP headers that protect against common attacks.

Enable HSTS Critical

Forces HTTPS and prevents downgrade attacks.

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

Prevent clickjacking Critical

Blocks your site from being embedded in iframes.

add_header X-Frame-Options "SAMEORIGIN" always;

Prevent MIME sniffing Important

Forces browsers to respect declared content types.

add_header X-Content-Type-Options "nosniff" always;

Configure Content-Security-Policy Important

Controls which resources can be loaded. Start permissive, then tighten.

add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; frame-ancestors 'self';" always;

Control referrer information Recommended

Limits what referrer info is sent to other sites.

add_header Referrer-Policy "strict-origin-when-cross-origin" always;

Disable dangerous features Recommended

Restricts access to browser features you don't need.

add_header Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()" always;

4. Access Control

Limit what requests are allowed.

Limit request body size Important

Prevents large uploads that could exhaust resources.

client_max_body_size 10m;  # Adjust based on your needs

Restrict HTTP methods Recommended

Only allow methods your application needs.

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

Block sensitive files Critical

Prevent access to configuration and hidden files.

# Block hidden files
location ~ /\. {
    deny all;
    return 404;
}

# Block common sensitive files
location ~* (\.git|\.env|\.htaccess|\.htpasswd|web\.config)$ {
    deny all;
    return 404;
}

Protect admin areas Important

Restrict access to admin panels by IP or authentication.

location /admin/ {
    allow 10.0.0.0/8;
    allow 192.168.0.0/16;
    deny all;
    
    # Or use basic auth
    # auth_basic "Admin Area";
    # auth_basic_user_file /etc/nginx/.htpasswd;
}

5. Rate Limiting

Protect against abuse and DDoS.

Configure request rate limiting Important

Limit requests per second from each client.

# In http block
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;

# In server/location
limit_req zone=req_limit burst=20 nodelay;
limit_req_status 429;

Limit concurrent connections Recommended

Prevent a single IP from opening too many connections.

# In http block
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

# In server/location
limit_conn conn_limit 20;
limit_conn_status 429;

6. Logging & Monitoring

Visibility into what's happening on your server.

Enable access logging Critical

Log all requests for security analysis.

access_log /var/log/nginx/access.log combined buffer=512k flush=1m;

Enable error logging Critical

Capture errors for debugging and security monitoring.

error_log /var/log/nginx/error.log warn;

Log security-relevant headers Recommended

Include useful info in access logs.

log_format security '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    '"$http_x_forwarded_for" $request_time';

access_log /var/log/nginx/security.log security;

7. Miscellaneous

Set proper timeouts Recommended

Prevent slowloris attacks and resource exhaustion.

client_body_timeout 10s;
client_header_timeout 10s;
keepalive_timeout 65s;
send_timeout 10s;

Limit buffer sizes Recommended

Prevent buffer overflow attacks.

client_body_buffer_size 16k;
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;

Run Gixy regularly Critical

Automate security scanning in your CI/CD pipeline.

# Install and run
pip install gixy-ng
gixy /etc/nginx/nginx.conf

# RPM alternative with ReDoctor-backed deep analysis
sudo dnf install https://extras.getpagespeed.com/release-latest.rpm
sudo dnf install gixy-deep
gixy --deep /etc/nginx/nginx.conf
Continuous Compliance For 24/7 security monitoring, GetPageSpeed Amplify tracks NGINX security automatically and alerts you when issues are detected.

Complete Example Configuration

Here's a minimal secure server block incorporating all critical items:

server {
    listen 443 ssl http2;
    server_name example.com;

    # TLS
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;

    # Security headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    # Hide version
    server_tokens off;

    # Limits
    client_max_body_size 10m;

    # Block hidden files
    location ~ /\. {
        deny all;
        return 404;
    }

    # Your application
    location / {
        # ...
    }
}