# 全局块
user nginx; # 运行用户
worker_processes auto; # 工作进程数
error_log /var/log/nginx/error.log warn; # 错误日志路径和级别
pid /var/run/nginx.pid; # PID文件位置
# 事件块
events {
worker_connections 1024; # 每个工作进程的最大连接数
use epoll; # 事件驱动模型
multi_accept on; # 是否一次性接受所有新连接
}
# HTTP块
http {
# 基础配置
include /etc/nginx/mime.types; # MIME类型文件
default_type application/octet-stream; # 默认MIME类型
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; # 访问日志
# 性能优化
sendfile on; # 启用sendfile
tcp_nopush on; # 仅在sendfile开启时有效
tcp_nodelay on; # 禁用Nagle算法
keepalive_timeout 65; # 保持连接超时时间
types_hash_max_size 2048;
# 服务器块
server {
listen 80; # 监听端口
server_name example.com; # 域名
location / {
root /usr/share/nginx/html; # 根目录
index index.html index.htm; # 默认文件
}
error_page 404 /404.html; # 错误页面
error_page 500 502 503 504 /50x.html; # 错误页面
}
}
# 工作进程和工作连接
worker_processes auto; # 自动设置为CPU核心数
worker_rlimit_nofile 100000; # 每个worker能打开的文件描述符数量
events {
worker_connections 4096; # 每个worker的最大连接数
use epoll; # Linux高效事件模型
accept_mutex on; # 启用互斥锁
accept_mutex_delay 500ms; # 互斥锁延迟
multi_accept on; # 一次接受所有新连接
}
http {
# 文件传输优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# 连接超时设置
keepalive_timeout 30;
keepalive_requests 1000;
client_header_timeout 10;
client_body_timeout 10;
send_timeout 10;
# 缓冲区设置
client_body_buffer_size 128k;
client_header_buffer_size 1k;
client_max_body_size 10m;
large_client_header_buffers 4 4k;
# 文件缓存
open_file_cache max=10000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
}
server {
listen 80;
server_name example.com www.example.com;
# 根目录设置
root /var/www/example.com;
index index.html index.php;
# 日志设置
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
# 默认location
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# PHP处理
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# 静态文件缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
access_log off;
add_header Cache-Control "public";
}
# 禁止访问隐藏文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
upstream backend {
# 负载均衡算法: round-robin(默认), least_conn, ip_hash, hash key
least_conn;
# 服务器列表
server backend1.example.com weight=5;
server backend2.example.com;
server backend3.example.com max_fails=3 fail_timeout=30s;
server backup1.example.com backup;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 超时设置
proxy_connect_timeout 5;
proxy_send_timeout 10;
proxy_read_timeout 10;
# 缓冲区设置
proxy_buffers 16 32k;
proxy_buffer_size 64k;
# 其他代理设置
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
server {
listen 443 ssl http2;
server_name example.com;
# SSL证书配置
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# SSL会话设置
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
# 协议和加密套件
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';
ssl_prefer_server_ciphers on;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# HSTS (HTTP Strict Transport Security)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# 其他安全头
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "strict-origin-when-cross-origin";
# 网站根目录
root /var/www/example.com;
index index.html;
# 强制HTTPS重定向
error_page 497 https://$host:$server_port$request_uri;
}
# 301永久重定向
server {
listen 80;
server_name old.example.com;
return 301 https://new.example.com$request_uri;
}
# 重写规则
server {
listen 80;
server_name example.com;
# 移除www前缀
if ($host ~* ^www\.(.*)) {
set $host_without_www $1;
rewrite ^(.*)$ http://$host_without_www$1 permanent;
}
# 重写URL
rewrite ^/old-url$ /new-url permanent;
# 动态URL重写
location /products {
rewrite ^/products/([0-9]+)/?$ /product.php?id=$1 last;
}
# 条件重写
if ($http_user_agent ~* (bot|crawler|spider)) {
rewrite ^(.*)$ /bot-page.html last;
}
}
# 代理缓存
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m use_temp_path=off;
server {
location / {
proxy_cache my_cache;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;
add_header X-Proxy-Cache $upstream_cache_status;
}
}
# FastCGI缓存
fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=FASTCGICACHE:100m inactive=60m;
server {
location ~ \.php$ {
fastcgi_cache FASTCGICACHE;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_valid 200 60m;
fastcgi_cache_valid 404 1m;
fastcgi_cache_methods GET HEAD;
fastcgi_cache_bypass $no_cache;
fastcgi_no_cache $no_cache;
add_header X-FastCGI-Cache $upstream_cache_status;
}
}
# 禁止非法域名访问
server {
listen 80 default_server;
server_name _;
return 444;
}
# 限制HTTP方法
server {
location /admin {
limit_except GET POST {
deny all;
}
}
}
# 防止点击劫持
add_header X-Frame-Options "SAMEORIGIN" always;
# 防止MIME类型嗅探
add_header X-Content-Type-Options "nosniff" always;
# 防止XSS攻击
add_header X-XSS-Protection "1; mode=block" always;
# 内容安全策略
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.example.com; img-src 'self' https://*.example.com data:; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; frame-src 'none'; object-src 'none';" always;
# 限制访问
location /admin {
allow 192.168.1.0/24;
allow 10.0.0.1;
deny all;
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd;
}
# 速率限制
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
server {
location /api/ {
limit_req zone=one burst=20 nodelay;
}
}
location /ws/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_min_length 256;
gzip_buffers 16 8k;
gzip_disable "MSIE [1-6]\.";
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
brotli_min_length 256;
location / {
root /var/www/html;
index index.html;
# 根据Accept-Language头重定向
if ($http_accept_language ~* ^zh) {
rewrite ^/$ /zh/index.html break;
}
if ($http_accept_language ~* ^en) {
rewrite ^/$ /en/index.html break;
}
# 默认语言
rewrite ^/$ /en/index.html break;
}
# 图片缩略图
location ~* ^/images/(.+)_(\d+)x(\d+)\.(jpg|jpeg|png|gif)$ {
set $file $1.$4;
set $width $2;
set $height $3;
image_filter resize $width $height;
image_filter_jpeg_quality 85;
image_filter_buffer 10M;
try_files /images/$file =404;
}
# WebP自动转换
location ~* ^/images/.+\.(jpg|jpeg|png)$ {
if ($http_accept ~* "webp") {
add_header Vary Accept;
rewrite ^/images/(.+)\.(jpg|jpeg|png)$ /images/$1.webp break;
}
}
# 自定义日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'rt=$request_time uct="$upstream_connect_time" uht="$upstream_header_time" urt="$upstream_response_time"';
log_format json_analytics escape=json
'{'
'"time_local":"$time_local",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"request":"$request",'
'"status": "$status",'
'"body_bytes_sent":"$body_bytes_sent",'
'"request_time":"$request_time",'
'"http_referrer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"http_x_forwarded_for":"$http_x_forwarded_for"'
'}';
# 条件日志记录
map $status $loggable {
~^[23] 0;
default 1;
}
server {
access_log /var/log/nginx/access.log main if=$loggable;
access_log /var/log/nginx/analytics.log json_analytics;
}
# 调试日志
error_log /var/log/nginx/debug.log debug;
# 变量转储
location /dump {
return 200 "
Host: $host\n
URI: $uri\n
Args: $args\n
Remote IP: $remote_addr\n
User Agent: $http_user_agent\n
Referer: $http_referer\n
Request Method: $request_method\n
Server Protocol: $server_protocol\n
";
}
# 请求头转储
location /headers {
return 200 "$http_user_agent";
add_header Content-Type text/plain;
}
# 重写日志
rewrite_log on;
模块化配置:将配置拆分为多个文件,使用include
指令包含
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
最小权限原则:使用非root用户运行Nginx
user www-data;
定期检查配置:在修改配置后运行测试
nginx -t
版本控制:将配置文件纳入版本控制系统
监控和日志轮转:设置日志轮转和监控Nginx状态
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
定期更新:保持Nginx版本更新以获得安全补丁和新功能
性能调优:根据服务器硬件和流量特点调整worker_processes和worker_connections
安全加固:禁用不必要的模块,限制敏感信息暴露
自动化部署:使用配置管理工具(Ansible, Chef, Puppet)管理Nginx配置
文档化:为每个自定义配置添加注释说明用途和修改记录