结论先行:将出海应用直接暴露到公网,Nginx 仍然是成熟度与控制力首屈一指的高性能反向代理。建议按阶段分步递进:先用模板 1 打通本地服务反代并透传真实客户端 IP;接着用模板 2 配合 Certbot 落地全自动 Let’s Encrypt HTTPS;前端单页应用直接套用模板 4 开启 Sendfile 与静态长期缓存;生产环境务必叠加模板 5 的安全响应头与限流规则。至于模板 3(负载均衡),待单机硬件利用率突破 70% 后再引入,切忌过早优化。
出海业务如果缺少 HTTPS 会失去用户信任,而反向代理配置纰漏则容易导致源站裸露、真实 IP 泄露甚至遭受跨站劫持。本文提炼 5 个经过真实生产环境检验的高频 Nginx 配置模板,助你开箱即用、规避各类安全隐患。
0、写在前面
新开辟一台 Linux VPS 后,把容器或本地进程安全可靠地暴露给公网访客,Nginx 依然是业界主流的高性能网关。
它在系统最外层承担五大职责:
- 统一流量入口:将 80/443 端口集中收敛,避免内部微服务端口杂乱外露;
- TLS/SSL 卸载终结:由 Nginx 处理昂贵的非对称加密计算,后端应用聚焦业务逻辑;
- 真实网络标头透传:确保后端程序获取客户端真实 IP、协议(HTTP/HTTPS)及原始 Host;
- 静态资源零拷贝托管:借助 Linux 内核
sendfile 机制,以极致效率直接响应前端构建产物;
- 边缘安全与速率限制:拦截恶意扫描、屏蔽危险敏感文件探测并施加连接限流。
本篇指南将这些高频工程场景整理为 5 套独立模板,并附带生产部署与排错清单。
1、期望目标
阅读并实操本篇指南后,你将达成以下目标:
- [ ] 掌握 Nginx 标准目录规范(
sites-available 与 sites-enabled)与软链接管理方式;
- [ ] 熟练套用模板 1(基础反向代理),完整透传客户端真实 IP 与 WebSocket 协议升级标头;
- [ ] 熟练套用模板 2(SSL 终结与 HTTP/2),结合 Certbot 实现全自动证书签发与轮询续期;
- [ ] 掌握模板 3(Upstream 负载均衡)在最少连接数(least_conn)与会话粘滞上的调度语法;
- [ ] 套用模板 4(静态单页托管),打通 Gzip 压缩、1年长期不可变缓存与 SPA 路由回退;
- [ ] 实施模板 5(生产安全加固),配置 HSTS、CSP、隐藏服务器指纹与高频接口限流。
2、技术选型与架构设计
为什么生产网关首选 Nginx
在出海基础设施中,对比传统多进程 Apache 或应用直出模式:
| 对比维度 |
Nginx (epoll 事件驱动) |
Apache (prefork/worker 模式) |
Node.js / Python 直连暴露 |
| 并发承载模型 |
单 Worker 异步非阻塞,轻量处理数万连接 |
多进程/线程并发,高并发下上下文切换损耗大 |
单事件循环,遇到长计算或慢请求易阻塞主线程 |
| 内存开销 |
常驻仅需 10~30MB 物理内存 |
随连接线性增长,容易消耗数百 MB 内存 |
基础运行时常驻 70~150MB+ |
| 静态文件吞吐 |
Linux sendfile 零拷贝,直接由内核送入网卡 |
需经过用户空间缓冲区复制 |
耗费 JavaScript/Python 虚拟机堆内存 |
| 抗攻击抗嗅探 |
灵活的 limit_req 漏桶限流与连接并发限制 |
依赖额外编译模块 |
原生能力薄弱,极易被慢连接攻击打满 |
Nginx 反向代理整体架构拓扑
3、5 套核心配置实战模板
模板 1:基础反向代理模板(含真实 IP 透传与 WebSocket)
适用于单机部署的 Node.js、Go、Python 或 Docker 容器应用。
配置文件:/etc/nginx/sites-available/your-app.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| server { listen 80; server_name yourdomain.com www.yourdomain.com;
access_log /var/log/nginx/yourapp-access.log; error_log /var/log/nginx/yourapp-error.log warn;
location / { 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_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;
proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s;
proxy_buffering on; proxy_buffer_size 128k; proxy_buffers 4 256k; }
location /healthz { proxy_pass http://127.0.0.1:3000/healthz; access_log off; } }
|
启用与重载命令
1 2 3 4 5 6 7 8
| sudo ln -sf /etc/nginx/sites-available/your-app.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo nginx -s reload
|
模板 2:生产级 SSL 终结模板(TLS 1.3 + HTTP/2 + 强制跳转)
当域名解析就绪后,通过 Certbot 申请 Let’s Encrypt 证书并应用强加密配置。
快速获取证书
1 2 3 4 5
| sudo apt update && sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
|
手动优化后的标准 SSL 站点配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| server { listen 80; listen [::]:80; server_name yourdomain.com www.yourdomain.com; return 301 https://$host$request_uri; }
server { listen 443 ssl; listen [::]:443 ssl; http2 on; server_name yourdomain.com www.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
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;
ssl_session_cache shared:SSL:10m; ssl_session_timeout 1d; ssl_session_tickets off;
ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/letsencrypt/live/yourdomain.com/chain.pem; resolver 1.1.1.1 8.8.8.8 valid=300s; resolver_timeout 5s;
location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; 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 https; } }
|
模板 3:多节点负载均衡模板(Upstream 调度与被动容灾)
当业务增长导致单机 CPU 持续高位时,配置 upstream 跨多实例调度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| upstream backend_cluster { least_conn;
server 10.0.0.11:3000 weight=3 max_fails=3 fail_timeout=30s; server 10.0.0.12:3000 weight=2 max_fails=3 fail_timeout=30s; server 10.0.0.13:3000 weight=1 max_fails=3 fail_timeout=30s;
server 10.0.0.14:3000 backup;
keepalive 32; }
server { listen 443 ssl; http2 on; server_name api.yourdomain.com;
location / { proxy_pass http://backend_cluster; proxy_http_version 1.1; proxy_set_header Connection ""; 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_next_upstream error timeout http_502 http_503 http_504; proxy_next_upstream_tries 3; } }
|
模板 4:前端静态文件托管模板(SPA 单页路由 + 缓存优化)
针对 React、Vue、Next.js 导出的纯静态生产环境构建产物(dist 目录)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| server { listen 443 ssl; http2 on; server_name app.yourdomain.com;
root /var/www/my-spa-project/dist; index index.html;
gzip on; gzip_vary on; gzip_min_length 1024; gzip_proxied any; gzip_comp_level 6; gzip_types text/plain text/css text/javascript application/javascript application/json application/xml image/svg+xml;
location ~* \.(?:css|js|woff2?|ttf|eot|svg|png|jpe?g|gif|ico|webp)$ { expires 1y; add_header Cache-Control "public, max-age=31536000, immutable"; access_log off; }
location ~* \.html$ { expires -1; add_header Cache-Control "no-cache, no-store, must-revalidate"; }
location / { try_files $uri $uri/ /index.html; }
location ~ /\. { deny all; access_log off; log_not_found off; } }
|
模板 5:生产安全加固模板(安全标头 + 限流防刷)
针对出海 SaaS 必须满足的安全审计基线。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| limit_req_zone $binary_remote_addr zone=api_limit_ip:10m rate=10r/s; limit_conn_zone $binary_remote_addr zone=addr_conn_limit:10m;
server { listen 443 ssl; http2 on; server_name yourdomain.com;
server_tokens off;
client_max_body_size 10M;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
location /api/ { limit_req zone=api_limit_ip burst=20 nodelay; limit_conn addr_conn_limit 10;
proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|OPTIONS)$ ) { return 405; } }
|
4、生产落地检查清单
配置修改完毕后,按照下列流程逐项校验:
| 校验模块 |
检查命令 / 操作方法 |
合格标准 |
| 语法核验 |
sudo nginx -t |
明确显示 test is successful |
| 热重载 |
sudo nginx -s reload |
返回码为 0,终端无错误打印 |
| 证书指纹 |
curl -Iv https://<域名> 2>&1 | grep -i 'ssl certificate' |
正确加载 Let’s Encrypt 证书链 |
| 跳转生效 |
curl -s -o /dev/null -w "%{http_code}" http://<域名> |
返回状态码为 301 或 308 |
| IP 透传 |
后端服务日志检查 X-Forwarded-For |
记录真实公网 IP,而非 127.0.0.1 |
| 安全响应头 |
`curl -I https://<域名> | grep -E 'Strict-Transport |
X-Frame’` |
5、高频故障与异常排查
Q1:执行 nginx -t 报错 duplicate upstream?
根本原因:在多个配置文件中声明了相同命名的 upstream 代码块,或者在包含目录时多次读取了同一个包含文件。
- 排查命令:
1
| grep -rn "upstream" /etc/nginx/
|
- 解决方式:确保每个
upstream 的名称全系统唯一,或统一汇聚在 /etc/nginx/conf.d/upstreams.conf 中声明。
Q2:访问页面返回 502 Bad Gateway?
根本原因:Nginx 无法与 proxy_pass 指定的目标建立 TCP 握手。
- 排查命令:
1 2 3 4 5
| sudo ss -tulpn | grep -E ':(3000|8080)\b'
sudo tail -n 30 /var/log/nginx/error.log
|
- 解决方式:若报错
Connection refused,说明后端应用根本没有启动或监听在错误的 IP 地址上(例如监听在 127.0.0.1 但请求来自容器网桥)。
Q3:静态文件访问返回 403 Forbidden?
根本原因:Linux 文件系统权限阻止了 Nginx 工作进程(通常为 www-data 或 nginx 用户)读取该文件目录。
- 解决方式:修正目录所有权与读执行权限:
1 2
| sudo chown -R www-data:www-data /var/www/your-app sudo chmod -R 755 /var/www/your-app
|
6、核心数据与行业参考
- 全球 Web 服务器份额基石:根据 W3Techs 最新统计,全球超 32% 的活跃站点以 Nginx 作为最外层接入网关,稳居行业前列。W3Techs Web Server Report
- HTTP/2 与 HTTP/3 部署演进:Cloudflare Radar 数据显示,全球边缘网络中 HTTP/2 与 HTTP/3 占比合计超 85%。Nginx 从 1.25.1 起对 HTTP/2 的配置指令进行了标准化演进,使用独立的
http2 on; 指令替代历史上的 listen 443 ssl http2; 语法。Nginx Release Changes
- Let’s Encrypt 签发规范:Let’s Encrypt 免费证书单注册域名上限为每周 50 张,采用 Certbot 的 systemd timer 每天两次检查并在剩余 30 天内自动发起更新。Let’s Encrypt Documentation
7、推荐工具与延伸阅读