记录一些个人常用的 NGINX 配置,方便随时复制。
默认配置修改
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 1048575;
charset utf-8;
events {
worker_connections 4096;
}
http {
client_max_body_size 0;
server_tokens off; # make stupid scanners happy
# gzip settings
gzip on;
gzip_comp_level 3;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied expired no-cache no-store private auth;
gzip_http_version 1.0; # for downstream NGINX
gzip_types text/plain text/css application/xml application/javascript application/json image/svg+xml font/x-woff font/opentype font/ttf;
# gzip_static for pre-compressed files
gzip_static on;
# real IP in logs
real_ip_header X-Forwarded-For;
real_ip_recursive on;
set_real_ip_from aaa.bbb.ccc.ddd/32;
# SSL related
ssl_dhparam /path/to/dhparam; # https://ssl-config.mozilla.org/ffdhe2048.txt
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
ssl_stapling on;
# TLS1.3 early data
ssl_early_data on;
proxy_set_header Early-Data $ssl_early_data;
}
HTTPS 与强制跳转
server {
listen 80;
listen [::]:80;
server_name example.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
带缓存的反向代理
upstream backend {
server 127.0.0.1:8080;
keepalive 32;
keepalive_timeout 60s; # be careful with RST from upstream
}
# cache settings
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=foo_cache:10m max_size=10g inactive=60m use_temp_path=off;
proxy_cache_lock on;
map $request_uri $bypass_cache {
default 0;
~*^/api/ 1;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
location ^~ /foo/ {
proxy_pass http://backend/bar/;
proxy_http_version 1.1;
# use resolver if upstream is a domain name
resolver 101.6.6.6 valid=60s;
# headers
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; # hardcode to https when proxying HTTPS with HTTP
# add upstream IP to XFF header
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # if not using remote_ip module
proxy_set_header X-Forwarded-For "$http_x_forwarded_for, $realip_remote_addr"; # if using remote_ip module (because $remote_addr is changed)
# WebSocket
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# set to off if not necessary
proxy_redirect default;
# set timeout
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
# check ssl certificate
proxy_ssl_certificate /path/to/cert.pem;
proxy_ssl_name example.com;
proxy_ssl_verify on;
# cache settings
proxy_cache foo_cache;
proxy_cache_bypass $bypass_cache;
proxy_cache_key $request_uri;
proxy_cache_valid 200 10m;
proxy_cache_valid 301 1m;
proxy_cache_revalidate on;
proxy_cache_use_stale updating;
proxy_cache_background_update on;
# buffering settings
proxy_buffering off;
proxy_request_buffering off;
# if buffer is enabled
proxy_temp_path /dev/shm/nginx 1 2; # use memory
}
NGINX buffering 的配置比较复杂,个人经验是应该在带宽较大一侧开启 buffer:如在客户端到前端的带宽显著大于前端到后端带宽时,应该启用 proxy_request_buffering
,反过来则开启 proxy_buffering
。
PHP FastCGI / Python UWSGI
Server 配置:
server {
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php {
fastcgi_pass unix:/var/run/php/php-fpm.sock;
include snippets/fastcgi-php.conf;
try_files $fastcgi_script_name =404;
}
location ~^ /py/ {
include snippets/python-uwsgi.conf;
}
}
snippets/fastcgi-php.conf
:
include fastcgi_params;
fastcgi_buffering off;
fastcgi_index index.php;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_param SCRIPT_FILENAME$realpath_root$fastcgi_script_name;
snippets/python-uwsgi.conf
:
include uwsgi_params;
uwsgi_buffering off;
uwsgi_pass unix:/tmp/uwsgi.sock;
uwsgi_param Host $host;
uwsgi_param X-Real-IP $remote_addr;
uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
uwsgi_param X-Forwarded-Proto $http_x_forwarded_proto;
fastcgi
和 uwsgi
模块同样有 buffering 和 cache 的配置,基本和反代的配置大同小异。
客户端限制
请求数限制
http {
limit_req_zone $binary_remote_addr zone=req_addr_limit:10m rate=5r/s;
}
location /bar/ {
limit_req zone=req_addr_limit burst=30 delay=20;
limit_req_dry_run on; # set to off to enable
limit_req_status 429; # default is 503
}
连接数限制
注:在 HTTP/2 和 HTTP/3 中,每个并发请求都被视作一个单独的连接。所以限制请求数基本就可以满足要求。
http {
limit_conn_zone $binary_remote_addr zone=conn_addr_limit:10m;
}
location /foo/ {
limit_conn zone=conn_addr_limit 20;
limit_conn_dry_run on; # set to off to enable
limit_conn_status 429; # default is 503
}
静态路径映射
关键:如果 location
是正则表达式,则 alias
指令不会保留后缀。也就是说,必须使用绝对 URI 查找文件。
用户家目录(恒等映射)
location ~ ^\/~(\w+)(\/.*)?$ {
alias /home/$1/public_html$2;
index index.html index.htm;
autoindex on;
}
非恒等映射
map $uri $actual_dir {
~^/foo/ alpha$1;
~^/bar/ bravo$1;
~^/baz/ charlie$1;
}
location ~ ^/(foo|bar|baz)(/|$) {
rewrite ^/([^/]*)$ /$1/ redirect;
root /common/root;
try_files /$actual_dir /$actual_dir/ /$actual_dir/index.html =404;
}
其他
- 配置生成器:DigitalOcean, Mozilla SSL Configuration Generator
- 从 CloudFlare IP 列表生成
set_real_ip_from
白名单:ergin/nginx-cloudflare-real-ip - 我的相关文章:带 NGINX Tag 的博客