在现代 Web 架构中,Nginx 凭借其高并发处理能力与极低的资源消耗,常被用作流量的统一入口。反向代理不仅能够隐藏后端服务真实 IP、实现负载均衡,还能通过静态资源缓存与 SSL 卸载减轻后端负担。而全站 HTTPS 已是当下安全合规的硬性要求,正确配置 Nginx 的反向代理与 HTTPS,是保障服务安全与稳定的关键前置环节。

核心原理

在典型的反向代理架构中,客户端与 Nginx 之间建立 HTTPS 加密连接,Nginx 对 SSL/TLS 握手进行处理并解密请求,随后以 HTTP(或向上 HTTPS)方式将明文请求转发给后端服务。这种机制称为 SSL 卸载。在此过程中,Nginx 需要在 HTTP 头部中注入 X-Forwarded-For 与 X-Forwarded-Proto 等字段,以保障后端服务仍可获取客户端真实 IP 与原始请求协议。

操作步骤与示例配置

1. 获取 SSL 证书

生产环境通常使用 Let's Encrypt 等权威 CA 签发免费证书,或购买商业证书。测试环境可自行生成私钥与自签证书:

# 生成私钥与自签证书,有效期 365 天
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/nginx/ssl/server.key \
  -out /etc/nginx/ssl/server.crt

2. 编写 Nginx 配置文件

以下为完整的反向代理与 HTTPS 配置示例,包含 HTTP 强制跳转、SSL 参数优化及反向代理核心指令:

# HTTP 服务块,强制跳转至 HTTPS
server {
    listen 80;
    server_name example.com;
    # 301 永久重定向,利于 SEO 与浏览器缓存
    return 301 https://$host$request_uri;
}

# HTTPS 服务块
server {
    listen 443 ssl http2;
    server_name example.com;

    # 指定证书与私钥路径
    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;

    # 优化 SSL 协议与加密套件,禁用不安全的 TLSv1/v1.1
    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 on;

    # 开启 OCSP Stapling 加速证书验证
    ssl_stapling on;
    ssl_stapling_verify on;

    # HSTS 头部,告知浏览器一年内仅使用 HTTPS 访问
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    location / {
        # 反向代理至后端服务
        proxy_pass http://127.0.0.1:8080;

        # 透传客户端真实 IP 与协议
        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 升级
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # 代理超时设置
        proxy_connect_timeout 60s;
        proxy_read_timeout 60s;
        proxy_send_timeout 60s;
    }
}

关键参数解释

  • listen 443 ssl http2:启用 HTTPS 并开启 HTTP/2 协议支持,提升传输效率。
  • ssl_protocols:限定仅允许 TLS 1.2 及 1.3,规避已知安全漏洞。
  • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for:将客户端 IP 追加至头部链路,防止经过多级代理后真实 IP 丢失。
  • proxy_set_header Upgrade $http_upgrade:处理 WebSocket 时的必须配置,否则长连接握手会被 Nginx 断开。

常见问题、注意事项与排错思路

1. 502 Bad Gateway 错误

  • 原因:Nginx 无法与后端建立连接,通常因后端服务未启动、监听端口不匹配或防火墙阻隔所致。
  • 排错:检查后端进程状态;确认 proxy_pass 指向的地址与端口无误;在 Nginx 所在机器使用 curl http://127.0.0.1:8080 测试内网连通性;查看 /var/log/nginx/error.log 获取具体连接拒绝原因。

2. 证书链不全导致浏览器报不安全

  • 原因:仅配置了终端证书而缺少中间 CA 证书,浏览器无法验证信任链。
  • 排错:确认 ssl_certificate 指向的 .crt 或 .pem 文件中是否包含了中间证书。可使用 openssl s_client -connect example.com:443 检查返回的证书链深度,若 verify return 非 0 则存在证书链问题。

3. 无限重定向循环 (ERR_TOO_MANY_REDIRECTS)

  • 原因:后端应用自身也强制跳转 HTTPS,但收到的是 Nginx 转发来的 HTTP 请求,导致循环。
  • 排错:确保后端应用信任 X-Forwarded-Proto 头部,依据该头部值而非请求本身的 scheme 来判断是否跳转;或直接关闭后端应用的 HTTPS 强制跳转逻辑,将安全控制全权交由 Nginx 处理。

4. 注意事项

  • 配置修改后务必先执行 nginx -t 验证语法,再执行 nginx -s reload 平滑重载,避免配置错误导致服务中断。
  • 若代理大文件上传接口,需在 location 块中调大 client_max_body_size 参数,默认 1M 会拦截大体积请求。
  • 密切关注 Let's Encrypt 等短期证书的过期时间,配置自动续期定时任务(如 certbot renew)以防服务瘫痪。

总结

Nginx 承担 SSL 卸载与反向代理,是分离安全层与业务逻辑的有效手段。配置时需严格限制 TLS 协议版本与弱加密套件,并准确透传真实 IP 与原始协议头部,以保障后端业务正常运转。面对 502 或重定向循环等问题,应优先聚焦 Nginx 错误日志与 HTTP 头部交互过程,精准定位断点。

主楼