Nginx 配置详解:反向代理、负载均衡与安全加固
Nginx 是生产环境最常用的 Web 服务器和反向代理。但很多人的 Nginx 配置只停留在「能用」——没有性能调优、没有安全加固、没有正确的 HTTPS 配置。本文从真实生产环境出发,覆盖 Nginx 配置的核心场景。
反向代理配置
基础反向代理
server {
listen 80;
server_name example.com www.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
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_set_header X-Forwarded-Proto $scheme;
}
}
WebSocket 代理
Node.js / Nuxt 项目中用了 WebSocket(如 HMR、实时通知),需要额外配置:
location /ws {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400; # WebSocket 长连接超时
}
SSE(Server-Sent Events)代理
location /api/stream {
proxy_pass http://127.0.0.1:3000;
proxy_buffering off; # 关闭缓冲,否则 SSE 会被攒着一起发
proxy_cache off;
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding on;
}
静态文件 + API 代理混合
server {
listen 80;
server_name example.com;
root /var/www/html;
# SPA 前端:所有未匹配的路由回退到 index.html
location / {
try_files $uri $uri/ /index.html;
}
# 静态资源:直接由 Nginx 处理(比 Node.js 快几倍)
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?|ttf)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# API 请求:代理到后端
location /api/ {
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;
}
# 上传文件大小限制
client_max_body_size 50m;
}
负载均衡
基础负载均衡
upstream backend {
# 默认轮询(round-robin)
server 192.168.1.10:3000;
server 192.168.1.11:3000;
server 192.168.1.12:3000;
}
加权负载均衡
upstream backend {
server 192.168.1.10:3000 weight=3; # 性能强的机器权重高
server 192.168.1.11:3000 weight=2;
server 192.168.1.12:3000 weight=1;
}
最少连接数(适合请求耗时差异大的场景)
upstream backend {
least_conn;
server 192.168.1.10:3000;
server 192.168.1.11:3000;
}
IP Hash(会话保持)
upstream backend {
ip_hash; # 同一 IP 总是分配到同一服务器
server 192.168.1.10:3000;
server 192.168.1.11:3000;
}
健康检查与故障转移
upstream backend {
server 192.168.1.10:3000 max_fails=3 fail_timeout=30s;
server 192.168.1.11:3000 max_fails=3 fail_timeout=30s;
server 192.168.1.12:3000 backup; # 备用,前面都挂了才启用
}
max_fails=3:30 秒内失败 3 次则标记为不可用fail_timeout=30s:标记不可用后 30 秒内不再尝试backup:备用服务器
HTTPS 配置
现代 HTTPS 配置
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
# SSL 证书
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# 只使用 TLS 1.2 和 1.3
ssl_protocols TLSv1.2 TLSv1.3;
# 加密套件
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# 会话缓存(减少 TLS 握手开销)
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# HSTS:强制浏览器后续都走 HTTPS
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
}
# HTTP 跳转 HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
使用 Certbot 自动管理 Let's Encrypt 证书
# 安装 certbot
sudo apt install certbot python3-certbot-nginx
# 自动获取并配置证书
sudo certbot --nginx -d example.com -d www.example.com
# 自动续期(certbot 会自动添加 cron)
sudo certbot renew --dry-run
安全加固
隐藏版本号
# nginx.conf
server_tokens off; # 不在响应头和错误页暴露 Nginx 版本
请求速率限制
# 定义限流区域
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
server {
# API 限流:平均 10 req/s,突发 20
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://backend;
}
# 登录接口更严格:1 req/s
location /api/login {
limit_req zone=login burst=5 nodelay;
proxy_pass http://backend;
}
}
并发连接数限制
limit_conn_zone $binary_remote_addr zone=conn:10m;
server {
limit_conn conn 10; # 每个 IP 最多 10 个并发连接
}
安全响应头
server {
# 防止点击劫持
add_header X-Frame-Options "SAMEORIGIN" always;
# XSS 保护
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# CSP 策略
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self' https://api.example.com;" always;
# Referrer 策略
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 权限策略
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
}
禁止访问敏感文件
location ~ /\.(git|env|htaccess) {
deny all;
return 404;
}
location ~ /\.(sql|bak|log|conf)$ {
deny all;
return 404;
}
性能优化
Gzip 压缩
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript
application/javascript application/json
application/xml application/rss+xml
application/atom+xml image/svg+xml;
Brotli 压缩(比 Gzip 压缩率更高)
# 需要 nginx brotli 模块
brotli on;
brotli_comp_level 4;
brotli_types text/plain text/css application/javascript application/json image/svg+xml;
缓冲区调优
# 代理缓冲区
proxy_buffer_size 16k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
# 客户端缓冲区
client_body_buffer_size 16k;
client_header_buffer_size 4k;
large_client_header_buffers 4 8k;
日志优化(生产环境减少 IO)
# 只记录错误和关键请求
access_log /var/log/nginx/access.log combined buffer=32k flush=5s;
# 静态资源不记日志
location ~* \.(js|css|png|jpg|svg)$ {
access_log off;
}
常用配置模板
Nuxt 3 SSR 部署
server {
listen 80;
server_name example.com;
# Nuxt SSR
location / {
proxy_pass http://127.0.0.1:3000;
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_set_header X-Forwarded-Proto $scheme;
# SSR 需要长连接超时
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
# Nuxt 静态资源(_nuxt/ 目录下的文件带 hash,可长期缓存)
location /_nuxt/ {
proxy_pass http://127.0.0.1:3000;
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# HMR WebSocket(仅开发环境需要)
location /_loading/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
灰度发布
# 利用 cookie 进行灰度分流
upstream stable {
server 192.168.1.10:3000;
}
upstream canary {
server 192.168.1.20:3000; # 新版本
}
map $cookie_version $upstream_pool {
default stable;
canary canary;
}
server {
location / {
proxy_pass http://$upstream_pool;
}
}
配置检查与重载
# 检查配置语法
sudo nginx -t
# 重载配置(不中断服务)
sudo nginx -s reload
# 查看当前连接数
nginx -V 2>&1 | grep -o with-http_stub_status_module
# 如果有 stub_status 模块,可以开启状态页检查连接数
总结
Nginx 配置的三个层次:
- 能用:反向代理 + HTTPS → 覆盖 80% 场景
- 好用:负载均衡 + 缓存 + Gzip → 性能提升
- 安全:限流 + 安全头 + 隐藏版本号 → 抵御常见攻击
建议把本文的配置模板保存下来,每次部署新项目时基于模板修改,避免从零开始。定期用 Mozilla SSL Config Generator 检查 SSL 配置是否跟上最新安全标准。
Comments | 0条评论