Skip to content

Commit

Permalink
chore: improve code comments and add some references
Browse files Browse the repository at this point in the history
  • Loading branch information
EsadCetiner authored Nov 27, 2024
1 parent 9bdab17 commit 0e10309
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 70 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ This project's goal is to provide a fast and secure by default NGINX configurati

## Before you install

To prevent DNS spoofing, the resolver directive within the http block is set to ``127.0.0.53``, your localhost DNS resolver may be located at a different IP address (127.0.0.11 for docker). DNS resolution may fail depending on your environment, monitor your error.log file and set the resolver directive to the correct IP address.
To prevent DNS spoofing, the resolver directive within the http block is set to use an localhost DNS stub resolver (which is 127.0.0.53 for most users, 127.0.0.11 for docker). DNS resolution will fail if your DNS stub resolver is not at 127.0.0.53, monitor your error.log file and update the `resolver` directive to use the correct IP address if your having issues.

Don't set the resolver directive to a public DNS server, only use the localhost DNS resolver.

Expand Down
111 changes: 43 additions & 68 deletions nginx.conf
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
# ----------------------------------------------------------------------------------------------
# Secure Nginx Config
# Secure NGINX Config
# Copyright (c) 2022-2024 Esad Cetiner
#
# This configuration template is distributed under GPLv2
# Please see the included LICENSE file for full details
# ----------------------------------------------------------------------------------------------

# CIS NGINX 2.2.1 v2.1.0
user www-data;
worker_processes auto;
worker_cpu_affinity auto;
pid /run/nginx.pid;

load_module modules/ngx_http_headers_more_filter_module.so;
# uncomment to use CrowdSec Nginx Bouncer with Lua
# uncomment to use CrowdSec NGINX Bouncer with Lua
# Load CrowdSec
# load_module modules/ndk_http_module.so;
# load_module modules/ngx_http_lua_module.so;
Expand All @@ -25,7 +26,7 @@ load_module modules/ngx_http_headers_more_filter_module.so;
# load_module modules/ngx_http_brotli_filter_module.so;
# load_module modules/ngx_http_brotli_static_module.so;

# Enable Jit for better regex performance
# Enable JIT for better regex performance
pcre_jit on;

events
Expand All @@ -36,7 +37,7 @@ events
}

# worker_rlimit_nofile = (worker_connections * 1) + 500
# worker_rlimit_nofile = (worker_connections * 2) + 500 if you use nginx as reverse proxy
# worker_rlimit_nofile = (worker_connections * 2) + 500 if you use NGINX as reverse proxy

worker_rlimit_nofile 33268;

Expand All @@ -51,74 +52,60 @@ http
include /etc/nginx/mime.types;
default_type application/octet-stream;

# Not specifying a webroot within a server block can have very severe consequences and
# potentially expose everything stored on the server to the internet, fully
# accessable for anybody with a web browser to view.
# This directive will set the default webroot to an empty webroot to avoid this miscconfiguration.
# Not specifying an webroot within a server block or location block can make
# files accessible to the interent that you weren't intending to be public.
# This sets an default empty webroot to avoid that from happening.
root /var/www/empty-webroot/;

# Use localhost resolver to prevent DNS spoofing attacks
# Specifying public DNS Servers within Nginx, even within your local network can result in DNS spoofing.
# Some of these issues have been fixed in Nginx, but not all.
# Try using 127.0.0.11 or 127.0.0.1 if DNS doesn't work or if you see "(111: Connection refused) while resolving" in your error.log
# This directive is required if your using CrowdSec Nginx Bouncer and connecting to a LAPI with a domain name.
# See - https://blog.zorinaq.com/nginx-resolver-vulns/

# Use local DNS stub resolver to prevent DNS spoofing attacks
# Specifying public DNS Servers within NGINX (Even within your local network) can result in
# DNS spoofing in some situations although most of these issues have been fixed.
# See README.md if you have this error in your log: (111: Connection refused)
# See: https://blog.zorinaq.com/nginx-resolver-vulns/
resolver 127.0.0.53;
resolver_timeout 60s;

# Redirect to HTTPS
# Redirect all HTTP Request to HTTPS by default
# CIS NGINX 4.1.1 v2.1.0
server
{
# Listen on port 80 with IPv4 and IPv6 as default server
listen [::]:80 default_server;
listen 80 default_server;

server_name _;

# Redirect all requests to HTTPS
return 301 https://$host$request_uri;

# Log Requests to default server block
access_log /var/log/nginx/default_access.log;
error_log /var/log/nginx/default_error.log;
}

# This default server block protects against host header injection attacks by
# ensuring that an request with an invalid host header won't be sent to your application, and will instead get a forbidden error.
# If you have any server blocks listening on ports other than 443, then you'll
# have to add those ports here to ensure all ports have full coverage.
# As a side effect, you may face fewer scans by bots scanning the internet by IP address.
# Protect against host header injection attacks by rejecting unknown hostnames.
# If you have server blocks listening on ports other than 443 then add those ports here.
# As a side effect, you'll face fewer attacks from bots attacking by IP address.
# CIS NGINX 2.4.2 v2.1.0
server
{
# Listen on port 443 with IPv4 and IPv6 as default server
listen [::]:443 ssl default_server;
listen 443 ssl default_server;

server_name _;

return 403;

# Log Requests to default server block
access_log /var/log/nginx/default_access.log;
error_log /var/log/nginx/default_error.log;

# It doesn't matter what certificate you use here, no legitimate traffic should be going to this server block.
# Use any certificate, it doesn't matter what you use here.
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
}

# VirtualHosts and configs includes
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*.conf;

##
# TLS Settings
##

# CIS NGINX 4.1.14, 4.1.12, 4.1.5 and 4.1.4 v2.1.0
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ecdh_curve X25519:X448:secp256r1:secp384r1:secp521r1:sect571r1;
# uncomment and replace above if you want 100% in key exchange for ssl labs
# ssl_ecdh_curve secp384r1:secp521r1:sect571r1;
# ssl_ecdh_curve secp384r1:secp521r1:sect571r1; # Use this for 100% on key-exchange on SSL labs
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
Expand All @@ -127,55 +114,46 @@ http
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

# OCSP settings
# Enable OCSP stapling
# CIS NGINX 4.1.7 v2.1.0
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem; # <- add path to cert chain for OCSP stapling

##
# Strip Headers
# Information Leakage
##

# Hide Nginx version from error pages
server_tokens off;

# Strip headers that may leak information about your application
# such as what scripting language is used, and the version.
# Hide server software/versions
# CIS NGINX 2.5.1 and 2.5.4 v2.1.0
proxy_hide_header X-Powered-By;
proxy_hide_header X-AspNet-Version;
proxy_hide_header X-AspNetMvc-Version;
proxy_hide_header X-Runtime;
proxy_hide_header X-Redirect-By;
server_tokens off;

# Strip Nginx Server header
# This won't remove nginx from error pages, you'll have to
# use the hide-nginx.conf snippet to completely hide nginx.
# Use the hide-nginx.conf snippet to fully hide the fact your using NGINX.
more_set_headers "Server : ";

##
# Common Security Headers
##

# The deprecated XSS auditor was originally meant to mitigate XSS attacks in unsafe code.
# It's been found that the XSS auditor does a poor job at mitigating XSS attacks and can even introduce
# XSS vulnerabilities in otherwise safe code. The XSS auditor has been replaced by the CSP policy header,
# which provides much stronger XSS protection than the XSS auditor, and can even stop other attacks like clickjacking.
# Most browsers have removed the XSS auditor due to the aforementioned security issues, for browsers that still support the
# XSS auditor you should explicitly disable it.
# See - https://portswigger.net/research/abusing-chromes-xss-auditor-to-steal-tokens
more_set_headers "X-XSS-Protection : 0";
# Tell browsers to not guess the MIME type, this can mitigate some XSS attacks.
more_set_headers "X-Content-Type-Options : nosniff"
# Old IE 8 header, this isn't used in modern browser however it is good practise to set this value to noopen
more_set_headers "X-XSS-Protection : 0"; # Disable insecure XSS auditor on old browsers see: https://portswigger.net/research/abusing-chromes-xss-auditor-to-steal-tokens
more_set_headers "X-Content-Type-Options : nosniff" # Don't guess mime type to avoid XSS CIS NGINX 5.3.2 v2.1.0
more_set_headers "X-Download-Options : noopen";
# Legacy HTTP header, enforces same origin policy for sites that use Adobe Flash and Microsoft Silverlight
more_set_headers "X-Permitted-Cross-Domain-Policies : none"
##
# Logging Settings
##
error_log /var/log/nginx/error.log;
# Always log by default
# CIS NGINX 3.3, 3.2, and 3.1 v2.1.0
access_log /var/log/nginx/default_access.log;
error_log /var/log/nginx/default_error.log info;
##
# Gzip Settings
Expand Down Expand Up @@ -225,24 +203,16 @@ http
# Uncomment to activate Brotli, make sure the Brotli module is installed and activated.
# include /etc/nginx/snippets/brotli.conf;
##
# GeoIP
##

# GeoIP (optional)
# geoip_country /usr/local/share/GeoIP/GeoIP.dat;
# geoip_city /usr/local/share/GeoIP/GeoLiteCity.dat;

##
# Performance and Cache
##
# See - https://www.nginx.com/blog/thread-pools-boost-performance-9x/
# See: https://www.nginx.com/blog/thread-pools-boost-performance-9x/
aio threads;
# 0-RTT with TLSv1.3 can significantly improve the performance of an initial TLS connection, especially if combined with HTTP3.
# This feature is disabled by default due to risks of replay attacks.
# See - https://blog.cloudflare.com/even-faster-connection-establishment-with-quic-0-rtt-resumption/
# See: https://blog.cloudflare.com/even-faster-connection-establishment-with-quic-0-rtt-resumption/
# Uncomment below to activate 0-RTT, make sure you are aware of the risks before activating.
# Per server block configuration is not supported.
# include /etc/nginx/snippets/0-rtt.conf;
Expand All @@ -253,10 +223,12 @@ http
##
# Limit concurrent connections to 130, most browsers will open up lots of concurrent connections but will never go above 100.
# CIS NGINX 5.2.4 v2.1.0
limit_conn_zone $binary_remote_addr zone=limit_per_ip:10m;
limit_conn limit_per_ip 130;
# Limit requests up to 500 per second per ip
# CIS NGINX 5.2.5 v2.1.0
limit_req_zone $binary_remote_addr zone=allips:10m rate=500r/s;
limit_req zone=allips burst=400 nodelay;
Expand All @@ -281,12 +253,15 @@ http
open_file_cache_errors off;
# Set size limits for headers and body
# CIS NGINX 5.2.3 v2.1.0
# TODO: test 5.2.2
client_max_body_size 20M;
client_header_buffer_size 5k;
large_client_header_buffers 2 2k;
client_body_buffer_size 32k;
# Keep timeouts low to mitigate slow loris like attacks
# CIS NGINX 2.4.4, 2.4.3, and 5.2.1 v2.1.0
client_body_timeout 10;
client_header_timeout 10;
keepalive_timeout 10;
Expand Down
2 changes: 1 addition & 1 deletion snippets/protect-sensitive-files.conf
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ location ~* (?:config\.(?:old\.)?(?:php|json)|config\.inc\.php|config\.sample\.p

# Block hidden dot files (And by extension all apache .ht files)
# A negative lookahead is used to exclude the .well-known directory
# CIS NGINX 2.5.3
# CIS NGINX 2.5.3 v2.1.0
location ~* /\.(?!well-known/) { deny all; }

# Owncloud CVE-2023-49103 https://nvd.nist.gov/vuln/detail/CVE-2023-49103
Expand Down
3 changes: 3 additions & 0 deletions snippets/security-headers.template
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@

# Prevent clickjacking by restricting iFrames
# See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
# CIS NGINX 5.3.1 v2.1.0
more_set_headers "X-Frame-Options : DENY";

# Remove the referer header
# CIS NGINX 5.3.4 v2.1.0
# See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
more_set_headers "Referrer-Policy : no-referrer";

Expand All @@ -38,6 +40,7 @@ more_set_headers "Cross-Origin-Resource-Policy : same-origin";
# CSP is an powerful header for preventing XSS attacks, iFrames and in general preventing unauthorized resources from loading.
# There are a ton of options here and a ton of values here, it's recommened to familiarize yourself with many of the options
# available within the CSP header.
# CIS NGINX 5.3.3 v2.1.0
# See: https://content-security-policy.com/
# WARNING: Some applications set their own CSP header, in this case you should not override it and let the application handle it.
more_set_headers "Content-Security-Policy : default-src 'none'; script-src 'none'; style-src 'none; font-src 'none'; connect-src 'none'; media-src 'none'; object-src 'none'; child-src 'none'; frame-src 'none'; worker-src 'none'; manifest-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; upgrade-insecure-requests";
Expand Down

0 comments on commit 0e10309

Please sign in to comment.