How to Harden Nginx: Essential Security Practices for Safer Web Servers

This guide provides a comprehensive, step‑by‑step hardening roadmap for Nginx, covering version hiding, directory protection, HTTPS enablement, custom error pages, CSP, file permissions, security headers, connection limits, IP whitelisting, SSL optimization, secure file uploads, common attack mitigations, logging best practices, and additional hardening measures to protect web services from a wide range of threats.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
How to Harden Nginx: Essential Security Practices for Safer Web Servers

Introduction

In the digital age, web security is critical, and Nginx, as a popular high‑performance web server, offers strong security features that must be properly configured to defend against threats. This guide presents a detailed hardening roadmap for system administrators and developers.

Hide Version Information

Nginx exposes its version in the HTTP response header by default. Adding server_tokens off; in the http, server or location block disables this disclosure.

Open the Nginx configuration file (usually /etc/nginx/nginx.conf or /usr/local/nginx/conf/nginx.conf).

Edit the file and add server_tokens off; inside the http block or each server block.

Save and exit the editor.

Test the configuration with nginx -t.

Reload Nginx using nginx -s reload.

# nginx.conf or a specific server file
http {
    # other configuration...
    server_tokens off;
    server {
        listen 80;
        server_name example.com;
        location / {
            root /var/www/html;
            index index.html index.htm;
        }
    }
}

Restrict Access to Sensitive Directories

Prevent external users from accessing files such as .htaccess or the .git directory by using location blocks with deny all;.

server {
    listen 80;
    server_name example.com;
    root /var/www/html;
    location ~ \.git {
        deny all;
    }
    location ~ \.ht {
        deny all;
    }
}

A custom 403 error page can be defined with error_page 403 /custom_403.html; and served from /usr/share/nginx/html.

server {
    listen 80;
    server_name example.com;
    root /var/www/html;
    error_page 403 /custom_403.html;
    location ~ \.git { deny all; }
    location ~ \.ht { deny all; }
    location = /custom_403.html {
        allow all;
        root /usr/share/nginx/html;
    }
}

Configure Custom Error Pages

Define custom pages for 404, 500, etc., to improve user experience and avoid leaking server details.

server {
    listen 80;
    server_name example.com;
    root /var/www/html;
    server_tokens off;
    error_page 404 /custom_404.html;
    error_page 500 502 503 504 /custom_50x.html;
    location = /custom_404.html { root /usr/share/nginx/html; internal; }
    location = /custom_50x.html { root /usr/share/nginx/html; internal; }
}

Enable HTTPS

Obtain an SSL certificate, generate a CSR, and configure Nginx to redirect HTTP to HTTPS and serve secure traffic.

# Generate CSR
openssl req -new -newkey rsa:2048 -nodes -out yourdomain.csr -keyout yourdomain.key

# Nginx HTTPS configuration
server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl;
    server_name yourdomain.com www.yourdomain.com;
    ssl_certificate /path/to/yourdomain.crt;
    ssl_certificate_key /path/to/yourdomain.key;
    ssl_trusted_certificate /path/to/intermediate.crt;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
    location / { root /var/www/html; index index.html index.htm; }
}

Apply Content Security Policy (CSP)

Add a CSP header to restrict resource loading and mitigate XSS and data‑injection attacks.

server {
    listen 80;
    server_name example.com;
    add_header Content-Security-Policy "default-src 'self'; img-src *; script-src 'self' 'unsafe-inline' 'unsafe-eval'";
}

For stricter policies, specify trusted script, style, image, and API sources, and disable objects and frames.

add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://trustedscripts.example.com; style-src 'self' https://trustedstyles.example.com; img-src 'self' data: https://trustedimages.example.com; connect-src 'self' https://api.example.com; object-src 'none'; frame-src 'none';";

Monitor violations with report-uri to a designated endpoint.

add_header Content-Security-Policy "default-src 'self'; report-uri /csp-report-endpoint";

Set Correct File Permissions

Use chmod 644 for files and chmod 755 for directories. Ensure the Nginx process runs under a non‑root user (e.g., nginx or www-data).

# Set file permissions
sudo chmod 644 /var/www/html/index.html /etc/nginx/nginx.conf /var/log/nginx/access.log
# Set directory permissions
sudo chmod 755 /var/www/html/
# Change ownership
sudo chown nginx:nginx /var/www/html/index.html
sudo chown root:nginx /etc/nginx/nginx.conf
sudo chown nginx:nginx /var/log/nginx/access.log

Configure Security Headers

# Clickjacking protection
add_header X-Frame-Options SAMEORIGIN;
add_header Content-Security-Policy "frame-ancestors 'self';";
# XSS protection
add_header X-XSS-Protection "1; mode=block";
# MIME‑type sniffing protection
add_header X-Content-Type-Options nosniff;
# Referrer policy
add_header Referrer-Policy "strict-origin-when-cross-origin";
# Additional CSP
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'self'; upgrade-insecure-requests;";

Limit Connections

Use ngx_http_limit_conn_module and ngx_http_limit_req_module to restrict concurrent connections and request rates per IP.

http {
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    server {
        location / { limit_conn addr 10; }
    }
    limit_req_zone $binary_remote_addr zone=req_zone:10m rate=20r/s;
    server {
        location / { limit_req zone=req_zone burst=5 nodelay; }
    }
}

Configure IP Whitelist

server {
    listen 80;
    server_name yourdomain.com;
    location /admin/ {
        allow 192.168.1.1;
        deny all;
        proxy_pass http://backend;
    }
}

Optimize SSL Configuration

server {
    listen 443 ssl http2;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
    ssl_prefer_server_ciphers on;
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 10s;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    ssl_session_tickets on;
}

Secure File Uploads

Limit upload size with client_max_body_size and prevent execution of uploaded scripts.

http {
    client_max_body_size 10m;
    server {
        listen 80;
        server_name example.com;
        location /upload {
            proxy_pass http://backend_server;
            client_max_body_size 10m;
        }
        location /uploads {
            alias /path/to/uploads;
            location ~* \.(php|pl|py|jsp|asp|sh|cgi)$ { deny all; }
        }
    }
}

Prevent Common Attacks

DDoS Mitigation

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m;
    server {
        location /login.html { limit_req zone=one; }
        limit_conn_zone $binary_remote_addr zone=addr:10m;
        location /shopping/ { limit_conn addr 10; }
        client_body_timeout 5s;
        client_header_timeout 5s;
    }
}

SQL Injection Mitigation

location / {
    if ($request_uri ~* [;'<>' ]) { return 444; }
    if ($args ~* [;'<>' ]) { return 444; }
    location ~* /(admin|backup|config|db|src)/ { deny all; }
}

XSS Mitigation

add_header X-XSS-Protection "1; mode=block";

Clickjacking Protection

add_header X-Frame-Options SAMEORIGIN;

Directory Traversal Protection

# Disable autoindex
server {
    listen 80;
    server_name example.com;
    location / { autoindex off; root /var/www/html; }
}
# Block "../" patterns
location ~ /\.\./ { deny all; }
# Correct alias usage
location /static/ { alias /var/www/static_files/; autoindex off; }

Log Security

http {
    log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" $msec "$connection" "$connection_requests" "$upstream_addr" "$upstream_response_time" "$request_time" "$gzip_ratio"';
    access_log /var/log/nginx/access.log main buffer=32k flush=1m;
    error_log /var/log/nginx/error.log warn;
    server {
        listen 80;
        server_name example.com;
        location / { root /var/www/html; index index.html; }
        error_log /var/log/nginx/example.error.log error;
    }
}

Other Security Measures

Disallow Script Execution

server {
    listen 80;
    server_name example.com;
    location /uploads/ {
        location ~* \.php$ { deny all; }
    }
}

Configure Timeouts

http {
    client_body_timeout 10s;
    client_header_timeout 10s;
    send_timeout 10s;
    keepalive_timeout 60s;
    client_max_body_size 1M;
    limit_rate 100k;
    server {
        listen 80;
        server_name example.com;
        location / { }
    }
}

Conclusion

By disabling unnecessary HTTP methods, hiding version information, limiting buffers, blocking unwanted crawlers, restricting IP access, controlling concurrency and rate, tuning timeouts, and adopting HTTPS with optimized SSL/TLS settings, Nginx security can be significantly strengthened. Proper CSP, regular log audits, minimal‑privilege operation, and keeping Nginx up‑to‑date complete a robust defense against both known and emerging threats.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

access controlNGINXWeb SecurityHTTPSSSLCSPServer Hardening
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.