CIS Nginx Benchmark
Secure configuration guidelines for Nginx web server and reverse proxy
v2.1.0 June 2024Overview
▶This CIS Benchmark provides prescriptive guidance for establishing a secure configuration posture for Nginx. Recommendations cover installation hardening, TLS configuration, security headers, request filtering, and information disclosure prevention.
| Section | Area | Focus |
|---|---|---|
| 1 | Initial Setup | Installation source, version management |
| 2 | Basic Configuration | Process user, permissions, timeouts |
| 3 | Logging | Access logs, error logs, log format |
| 4 | TLS / SSL | Certificates, protocols, ciphers, HSTS |
| 5 | Request Filtering & Headers | Rate limiting, buffer sizes, security headers |
| 6 | Information Disclosure | Server tokens, version hiding |
Profile Definitions
▶| Profile | Description | Intended Use |
|---|---|---|
| L1 | Level 1 — Web Server | Essential hardening for all Nginx deployments. |
| L2 | Level 2 — Web Server | Defense-in-depth. May require application and client testing. |
1 — Initial Setup
▶1.1 Installation
▶This recommendation verifies that Nginx Is Installed from Official Source on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to nginx Is Installed from Official Source may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
nginx -v # Verify installation source: rpm -qi nginx 2>/dev/null || dpkg -s nginx 2>/dev/null
Install from the official nginx.org repository or OS vendor packages. Avoid unverified third-party builds.
This recommendation verifies that Only Required Modules Are Compiled on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to only Required Modules Are Compiled may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
nginx -V 2>&1 | grep --color=auto -o -- '--with-[a-z_]*' # Review compiled modules for business need
Compile Nginx from source with only required modules. Disable unnecessary modules like --without-http_autoindex_module.
1.2 Software Updates
▶This recommendation verifies that Nginx Is the Latest Stable Version on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to nginx Is the Latest Stable Version may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
nginx -v # Compare against https://nginx.org/en/download.html
# Update via package manager: dnf update nginx # or apt upgrade nginx
2 — Basic Configuration
▶2.1 Process & Permissions
▶This recommendation verifies that Nginx Runs as Non-Root User on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to nginx Runs as Non-Root User may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
grep 'user ' /etc/nginx/nginx.conf # Should be: user nginx; (or www-data) ps -ef | grep nginx | grep -v grep
# /etc/nginx/nginx.conf: user nginx;
The ownership of Nginx Configuration Files Are should be set to Root. Correct file and directory ownership prevents unauthorized modification and maintains the integrity of the NGINX web server configuration.
Incorrect ownership of Nginx Configuration Files Are may allow unauthorized users to modify critical configuration or executable files. Ensuring correct ownership is essential for maintaining the integrity of the NGINX web server.
stat -c '%U:%G' /etc/nginx/nginx.conf /etc/nginx/conf.d/*.conf # Should be root:root
chown root:root /etc/nginx/nginx.conf chmod 644 /etc/nginx/nginx.conf
This recommendation verifies that the Nginx PID File Is Secured on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to the Nginx PID File Is Secured may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
ls -la /run/nginx.pid # Should be owned by root with restrictive permissions
# /etc/nginx/nginx.conf: pid /run/nginx.pid;
This setting controls whether autoindex is disabled on the NGINX web server. Disabling this feature reduces the attack surface by removing unnecessary functionality that could be exploited by an attacker.
Leaving autoindex enabled when it is not required unnecessarily expands the attack surface. An attacker could leverage this feature to gain unauthorized access or escalate privileges on the NGINX web server.
grep -r 'autoindex on' /etc/nginx/ # Should return empty
# Remove or set in all locations: autoindex off;
2.2 Timeouts & Limits
▶This recommendation configures the timeout for Keepalive on the NGINX web server. Appropriate timeout values limit the window of opportunity for attacks and ensure resources are released in a timely manner.
Failure to keepalive Timeout Is Set may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
grep keepalive_timeout /etc/nginx/nginx.conf # Should be reasonable (e.g., 10-65)
# /etc/nginx/nginx.conf (http block): keepalive_timeout 65;
This recommendation verifies that send_timeout Is Set on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to send_timeout Is Set may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
grep send_timeout /etc/nginx/nginx.conf
send_timeout 10;
This recommendation verifies that worker_connections Is Configured Appropriately on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to worker_connections Is Configured Appropriately may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
grep worker_connections /etc/nginx/nginx.conf
# /etc/nginx/nginx.conf (events block):
events {
worker_connections 1024;
}3 — Logging
▶3.1 Access & Error Logs
▶This setting controls whether access_log is enabled on the NGINX web server. Enabling this feature strengthens the security posture by enforcing the recommended configuration via nginx.conf or site configuration files.
Without access_log enabled, the NGINX web server may lack critical protections against known attack vectors. Enabling this control mitigates risk and aligns the deployment with industry-accepted security baselines.
grep -r 'access_log' /etc/nginx/ | grep -v '#' # Should NOT have "access_log off;" in production
# /etc/nginx/nginx.conf (http block): access_log /var/log/nginx/access.log main;
This recommendation verifies that error_log Is Configured with Appropriate Level on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to error_log Is Configured with Appropriate Level may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
grep 'error_log' /etc/nginx/nginx.conf # Should be at least 'warn' level
error_log /var/log/nginx/error.log warn;
This recommendation verifies that Log Files Have Proper Permissions on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to log Files Have Proper Permissions may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
ls -la /var/log/nginx/ # Files should be 640 or more restrictive, owned by root or nginx
chmod 640 /var/log/nginx/*.log chown root:adm /var/log/nginx/*.log
3.2 Log Format
▶This recommendation verifies that Custom Log Format Includes Required Fields on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to custom Log Format Includes Required Fields may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
grep log_format /etc/nginx/nginx.conf
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_x_forwarded_for" $request_time';4 — TLS / SSL Configuration
▶4.1 Certificate & Protocol
▶This recommendation verifies that HTTPS Is Enabled and HTTP Redirects to HTTPS on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to hTTPS Is Enabled and HTTP Redirects to HTTPS may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
grep -r 'ssl_certificate' /etc/nginx/ # Verify HTTP→HTTPS redirect exists: grep -r 'return 301' /etc/nginx/ | grep https
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}This setting controls whether Only TLS 1.2 and 1.3 is enabled on the NGINX web server. Enabling this feature strengthens the security posture by enforcing the recommended configuration via nginx.conf or site configuration files.
Without Only TLS 1.2 and 1.3 enabled, the NGINX web server may lack critical protections against known attack vectors. Enabling this control mitigates risk and aligns the deployment with industry-accepted security baselines.
grep ssl_protocols /etc/nginx/nginx.conf /etc/nginx/conf.d/*.conf # Should be: TLSv1.2 TLSv1.3
ssl_protocols TLSv1.2 TLSv1.3;
This recommendation verifies that SSL Certificate Key Has Proper Permissions on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to sSL Certificate Key Has Proper Permissions may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Find key path: grep ssl_certificate_key /etc/nginx/conf.d/*.conf # Check permissions: stat -c '%a %U %G' /etc/ssl/private/server.key # Should be 600 root root
chmod 600 /etc/ssl/private/server.key chown root:root /etc/ssl/private/server.key
4.2 Ciphers & HSTS
▶This recommendation verifies that Only Strong SSL Ciphers Are Used on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to only Strong SSL Ciphers Are Used may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
grep ssl_ciphers /etc/nginx/nginx.conf /etc/nginx/conf.d/*.conf grep ssl_prefer_server_ciphers /etc/nginx/nginx.conf
ssl_prefer_server_ciphers on; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
This recommendation verifies that Diffie-Hellman Parameters Are 2048 Bits or More on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to diffie-Hellman Parameters Are 2048 Bits or More may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
grep ssl_dhparam /etc/nginx/nginx.conf openssl dhparam -inform PEM -in /etc/nginx/dhparam.pem -text 2>/dev/null | head -1
# Generate 2048-bit DH parameters: openssl dhparam -out /etc/nginx/dhparam.pem 2048 # nginx.conf: ssl_dhparam /etc/nginx/dhparam.pem;
This setting controls whether HSTS is enabled on the NGINX web server. Enabling this feature strengthens the security posture by enforcing the recommended configuration via nginx.conf or site configuration files.
Without HSTS enabled, the NGINX web server may lack critical protections against known attack vectors. Enabling this control mitigates risk and aligns the deployment with industry-accepted security baselines.
grep -r 'Strict-Transport-Security' /etc/nginx/
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
This setting controls whether OCSP Stapling is enabled on the NGINX web server. Enabling this feature strengthens the security posture by enforcing the recommended configuration via nginx.conf or site configuration files.
Without OCSP Stapling enabled, the NGINX web server may lack critical protections against known attack vectors. Enabling this control mitigates risk and aligns the deployment with industry-accepted security baselines.
grep ssl_stapling /etc/nginx/nginx.conf
ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s;
5 — Request Filtering & Security Headers
▶5.1 Request Limits
▶This recommendation addresses the proper configuration of client_max_body_size on the NGINX web server. Proper configuration ensures the component operates securely and in accordance with organizational security policies.
Misconfiguration of client_max_body_size can lead to security gaps that may be exploited by attackers. A properly configured NGINX web server reduces exposure to both known vulnerabilities and configuration drift.
grep client_max_body_size /etc/nginx/nginx.conf
client_max_body_size 10m;
This recommendation verifies that Buffer Overflow Attacks Are Mitigated on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to buffer Overflow Attacks Are Mitigated may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
grep -E 'client_body_buffer_size|client_header_buffer_size|large_client_header_buffers' /etc/nginx/nginx.conf
client_body_buffer_size 1k; client_header_buffer_size 1k; large_client_header_buffers 4 8k;
This recommendation addresses the proper configuration of Rate Limiting on the NGINX web server. Proper configuration ensures the component operates securely and in accordance with organizational security policies.
Misconfiguration of Rate Limiting can lead to security gaps that may be exploited by attackers. A properly configured NGINX web server reduces exposure to both known vulnerabilities and configuration drift.
grep -r limit_req /etc/nginx/
# In http block: limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s; # In server/location block: limit_req zone=one burst=20 nodelay;
This setting ensures that Allowed HTTP Methods is restricted on the NGINX web server. Restricting this capability limits potential abuse and enforces the principle of least privilege across the environment.
Unrestricted Allowed HTTP Methods could allow unauthorized users or processes to perform actions beyond their intended scope. Applying least-privilege principles to the NGINX web server is essential for defense in depth.
grep -r 'limit_except\|if.*request_method' /etc/nginx/
# In location blocks:
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 405;
}5.2 Security Headers
▶This recommendation verifies that X-Frame-Options Header Is Set on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to x-Frame-Options Header Is Set may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
grep -r 'X-Frame-Options' /etc/nginx/
add_header X-Frame-Options "SAMEORIGIN" always;
This recommendation verifies that X-Content-Type-Options Header Is Set on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to x-Content-Type-Options Header Is Set may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
grep -r 'X-Content-Type-Options' /etc/nginx/
add_header X-Content-Type-Options "nosniff" always;
This recommendation verifies that Content-Security-Policy Header Is Set on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to content-Security-Policy Header Is Set may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
grep -r 'Content-Security-Policy' /etc/nginx/
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'" always;
This recommendation verifies that Referrer-Policy Header Is Set on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to referrer-Policy Header Is Set may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
grep -r 'Referrer-Policy' /etc/nginx/
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
6 — Information Disclosure
▶6.1 Server Identity
▶This setting controls whether server_tokens is disabled on the NGINX web server. Disabling this feature reduces the attack surface by removing unnecessary functionality that could be exploited by an attacker.
Leaving server_tokens enabled when it is not required unnecessarily expands the attack surface. An attacker could leverage this feature to gain unauthorized access or escalate privileges on the NGINX web server.
grep server_tokens /etc/nginx/nginx.conf # Should be: server_tokens off; curl -sI http://localhost | grep Server
# /etc/nginx/nginx.conf (http block): server_tokens off;
This recommendation verifies that Default Error and Index Pages Are Customized on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to default Error and Index Pages Are Customized may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check for custom error pages: grep error_page /etc/nginx/nginx.conf /etc/nginx/conf.d/*.conf
# In server block:
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;
}This recommendation verifies that Hidden Files Are Not Served on the NGINX web server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to hidden Files Are Not Served may leave the NGINX web server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
grep -r 'location.*\.' /etc/nginx/ | grep deny
# In server block:
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}