Security Hardening in NGINX

1. Base Configuration & Global Security Settings

Start by tuning global settings for performance and security. That are-

  • Disable server tokens to prevent attackers from learning details about your NGINX version.

  • Resolver for DNS lookups.

  • Define a mapping to generate a CSP nonce based on the request ID.

  • A second map filters out suspicious User-Agent strings to block common malicious bots.

nginx.conf (Global Part):

# Global settings
worker_processes auto;
events {
    worker_connections 1024;
    multi_accept on;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    client_max_body_size 20M;

    # Use a public DNS resolver for upstream lookups
    resolver 8.8.8.8 valid=10s;

    # Disable NGINX version info in error pages and headers
    server_tokens off;

    keepalive_timeout 65;  # Keeps connections open for reuse up to 65 seconds
    sendfile on;           # Enable zero-copy file transmission
    tcp_nodelay on;        # Disable Nagle's algorithm to reduce latency
    tcp_nopush on;         # Optimize packet transmission (commonly used with sendfile)

    gzip on;
    gzip_comp_level 5;            # Compression level (1-9)
    gzip_min_length 256;          # Only compress responses larger than 256 bytes
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss;
    gzip_vary on;

    # Map to generate a nonce for CSP headers based on $request_id
    map $request_id $csp_nonce {
        "~*" $request_id;
    }

    # Map to match suspicious or malicious User-Agent strings
    # use this carefully as it will block crawlers also
    map $http_user_agent $bad_user_agent {
        default 0;
        ~*^$ 1;               # Empty User Agent
        ~*bot 1;              # Bots (use caution, some legitimate bots may be blocked)
        ~*spider 1;
        ~*crawl 1;
        ~*[<>]script 1;       # Potential XSS attempts
        ~*(nmap|nikto|wikto|sf|sqlmap|bsqlbf|w3af|acunetix|havij|appscan) 1;
    }

    # Include additional project configuration
    include app.conf;
}

Explanation:

  • worker_processes/worker_connections: Set up to efficiently handle concurrent connections.

  • server_tokens off: Prevents disclosing NGINX version details.

  • Resolver: Ensures proper DNS lookups.

  • Maps ($csp_nonce, $bad_user_agent): Dynamically generate CSP nonces and block obvious bad bots, mitigating issues like injection (OWASP Injection) and reconnaissance (vulnerable components).


2. SSL/TLS Setup & HTTP to HTTPS Redirection

Securing connections with SSL/TLS is essential. We can use Let’s Encrypt (via Certbot) in production. For internal services or testing, self‑signed certificates may suffice.

A. Using Let’s Encrypt with Certbot

For “example.com” and subdomains (e.g., “app.example.com”), configure an HTTP server block to redirect all traffic to HTTPS, then configure an HTTPS server block.

HTTP to HTTPS Redirect:

HTTPS Server Block (SSL/TLS with Let’s Encrypt):

Explanation:

  • HTTP to HTTPS redirection: Ensures all connections are encrypted, mitigating data eavesdropping (OWASP Cryptographic Failures).

  • SSL protocols and HSTS: Force modern TLS standards and protect against downgrade attacks.

B. Self-Signed Certificates

For internal or development environments, self-signed certificates can be used.

Why? While not trusted by browsers, self-signed certificates provide encryption for testing or internal communications.


3. Security Headers & Content Security Policy (CSP)

Security headers help prevent many common attacks. We set up several headers such as X‑Frame‑Options, X‑XSS‑Protection, and a detailed CSP header that also accommodates trusted third‑party services (e.g., Google APIs, CDN providers).

Example Security Headers

Explanation: These headers reduce the risk of clickjacking, XSS, MIME type confusion, and data leakage. The CSP header is tuned to allow scripts and styles from trusted sources (e.g., Google APIs, cdn.jsdelivr.net) and uses a nonce to allow inline scripts only when authorized.


4. Mitigating SQL Injection

Although preventing SQL injection is primarily an application-layer responsibility (using parameterized queries), NGINX can help filter out malicious requests.

Why? This simple pattern-based filter adds an extra layer of protection by rejecting obviously malicious requests, though backend validation remains essential.

4. DDoS Protection & Rate Limiting

Protect your server from abuse and DDoS attacks by limiting the number of requests from a single client.

Rate Limiting Example:

Explanation: This configuration limits clients to 10 requests per second (with bursts of up to 20), helping prevent abuse and service disruption (mitigating OWASP’s Insecure Design and Vulnerable Components).


5. Access Restrictions by IP, GeoIP, and User-Agent

Limit access to sensitive endpoints by IP, geographical region, or by filtering malicious user agents.

A. IP-based Restrictions

B. User-Agent Filtering

In our global configuration, we mapped suspicious User-Agents to a variable ($bad_user_agent). Then, within the server block, we block those requests:

Explanation: These restrictions help mitigate unauthorized access and reduce attack surfaces (addressing Broken Access Control and Identification Failures).

C. Restricting by GeoIP

(Requires GeoIP module and database.)

Why? GeoIP restrictions reduce malicious traffic from regions where you do not operate, improving overall security posture.


6. Blocking Sensitive Directories and Files

Prevent access to internal or version control directories that could expose sensitive data.

Explanation: Blocking these directories prevents attackers from accessing configuration files and repository data, reducing risk of information disclosure.


7. Blocking Bots & Bad Traffic with ModSecurity

ModSecurity is a robust web application firewall (WAF) that integrates with NGINX to block malicious traffic, bots, and a wide range of web attacks (from SQL injection to XSS), further hardening your server against the OWASP Top 10 vulnerabilities. [ We need to install this module ]

Why? ModSecurity, when combined with the OWASP Core Rule Set (CRS), can automatically block many common vulnerabilities and malicious requests, enhancing your server’s security.

8. Proxying to Backend & Handling Subdomains

When using NGINX as a reverse proxy for dynamic content, you may host multiple subdomains. For example, a subdomain like “marine.example.com” can proxy traffic to your backend server.

Subdomain Proxy Example (Marine UI):

Explanation:

  • Subdomains: This server block handles “marine.example.com” with similar security settings while proxying requests to “backend.com:8080.”

  • Allowed Origin: Ensures that CSP and CORS-related headers use a trusted origin.


9. Mitigating OWASP Top 10 Vulnerabilities

Here’s how our configuration helps mitigate common OWASP risks:

  1. Broken Access Control:

    • Use IP-based restrictions and enforce HTTPS with HSTS.

    • Backend must also implement authentication/authorization.

  2. Cryptographic Failures:

    • Enforce strong TLS protocols, secure ciphers, and HSTS.

  3. Injection (SQL, Command, etc.):

    • Simple query string filters help block obvious injection patterns.

    • Application-level sanitization remains critical.

  4. Insecure Design:

    • Layered security with proper headers, rate limiting, and access controls.

  5. Security Misconfiguration:

    • Regularly update configurations and disable server tokens.

  6. Vulnerable and Outdated Components:

    • Keep NGINX and modules up to date.

  7. Identification and Authentication Failures:

    • Enforce HTTPS and restrict sensitive endpoints.

  8. Software and Data Integrity Failures:

    • Use secure transmission (SSL/TLS) and signed updates.

  9. Security Logging and Monitoring Failures:

    • Ensure thorough logging and integrate ModSecurity.

  10. Server-Side Request Forgery (SSRF):

    • Validate upstream requests and restrict access via firewall rules.


10. Final Consolidated Configuration

Below is the final, consolidated configuration incorporating all the suggestions, modified to use “example.com” and “backend.com:8080.” It also considers subdomains and third-party services.

Explanation of Final Config:

  • Global & HTTP Settings: Optimize performance and security globally (worker settings, DNS resolver, etc.).

  • SSL/TLS and HSTS: Ensure all connections are encrypted and browsers enforce HTTPS.

  • Security Headers & CSP: Prevent clickjacking, XSS, MIME sniffing, and control resource loading, including allowances for trusted third-party services.

  • Rate Limiting & Access Restrictions: Deter DDoS attacks and block malicious traffic (via IP/User-Agent/GeoIP as needed).

  • Subdomain Handling: Demonstrates how to configure subdomains (e.g., marine.example.com) to proxy to your backend.

  • OWASP Top 10 Mitigations: Address vulnerabilities (injection, broken access, cryptographic failures, etc.) via layered configuration.

  • ModSecurity Integration: Adds a WAF layer to further protect against web attacks.


Last updated