Last active
January 16, 2024 13:59
-
-
Save andrejcremoznik/f0036b58398cafaa9b14ff04030646da to your computer and use it in GitHub Desktop.
Production Nginx config (HTTPS + rate limiting + PHP)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Server directives (place in /etc/nginx/sites-enabled/domain.tld.conf) | |
# http://domain.tld --> https://domain.tld | |
# http://www.domain.tld --> https://domain.tld | |
server { | |
listen 80; | |
listen [::]:80; | |
server_name domain.tld www.domain.tld; | |
return 301 https://domain.tld$request_uri; | |
} | |
# https://www.domain.tld --> https://domain.tld | |
server { | |
listen 443 ssl http2; | |
listen [::]:443 ssl http2; | |
server_name www.domain.tld; | |
# Include SSL configuration (see ssl.conf) | |
include /etc/nginx/conf.d/ssl.conf; | |
# Include certificates (Let's Encrypt path examples) | |
ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem; | |
ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem; | |
ssl_trusted_certificate /etc/letsencrypt/live/domain.tld/chain.pem; | |
# HSTS (Careful with this setting!) | |
#add_header Strict-Transport-Security "max-age=63072000; preload" always; | |
return 301 https://domain.tld$request_uri; | |
} | |
# https://domain.tld | |
server { | |
listen 443 ssl http2; | |
listen [::]:443 ssl http2; | |
server_name domain.tld; | |
# Include SSL configuration (see ssl.conf) | |
include /etc/nginx/conf.d/ssl.conf; | |
ssl_buffer_size 8k; # default 16k - affects time to first byte, optimal value depends on your site | |
# Include certificates (Let's Encrypt path examples) | |
ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem; | |
ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem; | |
ssl_trusted_certificate /etc/letsencrypt/live/domain.tld/chain.pem; | |
# HSTS (Careful with this setting!) | |
#add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; | |
root /srv/http/domain.tld/current/web; | |
index index.html index.php; | |
# Custom logs | |
access_log /var/log/nginx/access.domain.tld.log main if=$loggable; | |
error_log /var/log/nginx/error.domain.tld.log error; | |
# Allow bigger upload size (also adjust PHP POST size) | |
client_max_body_size 20m; | |
# Cache opened files descriptors | |
open_file_cache max=1000 inactive=20s; | |
open_file_cache_valid 30s; | |
open_file_cache_min_uses 2; | |
open_file_cache_errors on; | |
# Prevent mobile network providers from modifying your site | |
add_header Cache-Control "no-transform"; | |
# Immediately respond to Certbot requests | |
location /.well-known { try_files $uri =404; } | |
# Prevent access to scripts in uploads directory | |
location ~* ^\/app\/uploads\/.*\.(?:php|js|html?)$ { deny all; } | |
# Expire rules for static content | |
location ~* \.(?:manifest|appcache)$ { add_header Cache-Control "max-age=0"; } | |
location ~* \.(?:rss|atom)$ { add_header Cache-Control "max-age=3600"; } | |
location ~* \.(?:css|js|jpg|gif|png|ico|gz|svg|mp4|m4v|ogg|ogv|webm|woff2?)$ { | |
add_header Cache-Control "max-age=31536000, public, immutable"; | |
access_log off; | |
# Immediately return static file to avoid the rate-limited default block below | |
try_files $uri =404; | |
} | |
# Pass PHP files to PHP-FPM | |
location ~ \.php$ { | |
try_files $uri =404; | |
fastcgi_pass unix:/run/php-fpm/php-fpm.sock; # FIXME: configure PHP FPM listener address | |
fastcgi_index index.php; | |
fastcgi_read_timeout 60s; # Should match max_execution_time in PHP | |
include fastcgi_params; | |
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | |
} | |
# Default rewrites for WordPress permalinks | |
location / { | |
limit_req zone=php burst=3 nodelay; # Requests limited to 1/s, but allow bursts of 3 | |
try_files $uri $uri/ /index.php$is_args$args; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Main Nginx config (/etc/nginx/nginx.conf) | |
user http http; # FIXME: configure correct user/group for your web server | |
worker_processes auto; | |
worker_rlimit_nofile 8192; | |
events { worker_connections 8000; } | |
pid /run/nginx.pid; | |
#include /etc/nginx/modules-enabled/*.conf; | |
http { | |
server_tokens off; | |
include mime.types; | |
default_type application/octet-stream; | |
charset utf-8; | |
limit_req_zone $binary_remote_addr zone=php:10m rate=1r/s; | |
limit_req_status 444; | |
# Exclude 2xx and 3xx from access log | |
map $status $loggable { | |
~^[23] 0; | |
default 1; | |
} | |
log_format main '$remote_addr [$time_iso8601] "$request" $status "$http_referer" "$http_user_agent"'; | |
access_log /var/log/nginx/access.log main if=$loggable; | |
error_log /var/log/nginx/error.log error; | |
keepalive_timeout 20s; | |
sendfile on; | |
tcp_nopush on; | |
etag off; | |
gzip on; | |
gzip_comp_level 5; | |
gzip_min_length 256; | |
gzip_proxied any; | |
gzip_vary on; | |
gzip_types | |
application/atom+xml | |
application/javascript | |
application/json | |
application/manifest+json | |
application/rss+xml | |
application/wasm | |
application/xml | |
image/svg+xml | |
text/css | |
text/plain; | |
server { | |
listen 80 default_server; | |
return 444; | |
} | |
include sites-enabled/*.conf; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# SSL configuration (place in /etc/nginx/conf.d/ssl.conf and include in server directives) | |
# Adjusted for modern browser compatibility. Reference: https://ssl-config.mozilla.org/ | |
ssl_protocols TLSv1.3; | |
ssl_prefer_server_ciphers off; | |
ssl_session_cache shared:SSL:10m; | |
ssl_session_timeout 1d; | |
ssl_session_tickets off; | |
ssl_stapling on; | |
ssl_stapling_verify on; | |
resolver | |
1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001] | |
8.8.8.8 8.8.4.4 [2001:4860:4860::8888] [2001:4860:4860::8844] | |
valid=60s; | |
resolver_timeout 2s; | |
keepalive_timeout 300s; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment