nginx 支持 ssl 卸载与重加密组合策略:卸载即终止 tls 并转发明文至非 tls 后端,重加密则对明文流量重新 tls 封装以对接 tls 感知服务;混合模式下可结合 ssl_preread 按 sni 动态决策卸载、透传或重加密。

Nginx 在多层代理架构中,SSL 卸载与重加密不是互斥操作,而是可按需组合的两种 TLS 处理策略:前者在入口终止加密、向后端发明文;后者在出口重新加密封装、对接 TLS 感知服务。关键在于明确每个环节的 TLS 边界——卸载在哪结束,重加密从哪开始。
SSL 卸载:解密后交由非 TLS 后端
这是最常见场景,适用于后端服务本身不支持或无需处理 TLS(如旧版 MySQL、Redis、HTTP API 服务)。
- 客户端 HTTPS 请求抵达 Nginx 的 443 端口,Nginx 使用
ssl_certificate和ssl_certificate_key完成 TLS 握手与解密 - 解密后的明文流量(HTTP 或纯 TCP)通过
proxy_pass转发给后端,例如http://10.0.1.5:8080或backend:6379 - 必须设置
proxy_set_header X-Forwarded-Proto $scheme,让后端知晓原始请求是 HTTPS,避免跳转错误或混合内容问题 - 若后端需识别真实客户端 IP,还需透传
X-Real-IP和X-Forwarded-For
SSL 重加密:明文入、TLS 出,对接 TLS 后端
当后端服务要求 TLS 连接(如现代 gRPC 服务、启用了 mTLS 的数据库网关),Nginx 需在转发前重新加密流量。
- Nginx 接收客户端 TLS 请求(可终止,也可透传),解密后得到明文;或直接以 stream 模式透传 TLS 流量(不终止)
- 使用
proxy_ssl_certificate和proxy_ssl_certificate_key配置客户端证书,用于向上游发起双向 TLS(mTLS)连接 - 启用
proxy_ssl_verify on并指定proxy_ssl_trusted_certificate,校验上游服务器证书合法性 - 支持 ALPN 协商(如
proxy_ssl_alpn "h2;http/1.1"),确保协议兼容性,尤其对 gRPC/HTTP2 很关键
混合模式:卸载 + 重加密 + SNI 路由
在统一入口(如 443 端口)承载多个 TLS 服务时,Nginx 可结合 ssl_preread 和 stream 模块实现智能分发。
- 启用
stream { ssl_preread on; },在 TLS 握手初期读取 SNI 字段,不等待完整解密 - 根据
$ssl_preread_server_name匹配不同 upstream(如db-a.example.com → mysql-cluster-1,api.b.example.com → grpc-backend) - 对 MySQL 类服务走 TLS 透传(不卸载),对 gRPC 服务则先卸载再重加密(支持 ALPN 路由与 header 注入)
- 此模式下,卸载与重加密不再是全站统一策略,而是按域名/协议动态决策
配置要点与避坑提醒
实际部署中,几个细节容易引发连接失败或安全降级:
-
证书路径权限:Nginx worker 进程需有读取
.key文件权限,但不能被其他用户读取(建议chmod 600) -
协议与密码套件对齐:前后端 TLS 版本(如仅启用 TLSv1.3)和 ciphers 必须有交集,否则握手失败;可用
openssl s_client -connect host:port -tls1_3验证 -
timeouts 设置:四层代理中
proxy_timeout和proxy_responses影响长连接稳定性,尤其对数据库类 TCP 流量不可忽略 -
日志与调试:开启
error_log /var/log/nginx/error.log debug;可捕获 TLS 握手阶段错误(如证书链不全、SNI 不匹配)











