Nginx stream模块不能直接做SSL终止,但可通过ngx_stream_ssl_module构建TLS加密隧道:支持TLS终止+明文转发(模式一)或SNI路由+TLS透传(模式二),需编译启用--with-stream和--with-stream_ssl_module,并在stream上下文中配置ssl_preread、map及proxy_ssl等指令。

不能直接用 Nginx stream 模块做 SSL 终止来处理纯 TCP 流量,但可以借助 ngx_stream_ssl_module 构建高性能、可控的 TLS 加密隧道——本质是让 Nginx 在四层代理链路中充当 TLS 中继节点,既不暴露明文,也不强制后端改造。
确认模块可用并启用 stream 上下文
必须确保 Nginx 编译时已启用两个关键模块:
–with-stream
–with-stream_ssl_module
运行 nginx -V 2>&1 | grep -E 'with-stream|stream_ssl' 验证输出是否包含这两项。若缺失,需重新编译或换用官方预编译包(如 nginx.org 的 stable 版)。
配置必须写在 nginx.conf 顶层,与 http 块平级,不可嵌套其中:
# 配置内容放这里
}
构建 TLS 加密隧道的两种核心模式
模式一:TLS 终止 + 明文转发(SSL 卸载)
适用于后端服务不支持 TLS(如老版本 Redis、MySQL),由 Nginx 统一终结 TLS,再以明文连接上游:
- 在 server 块中配置 ssl_certificate 和 ssl_certificate_key
- 不启用 proxy_ssl 系列指令,因为上游走的是普通 TCP
- 客户端到 Nginx 是加密的,Nginx 到后端是明文的,性能开销集中在 Nginx 侧
模式二:TLS 透传(SNI 路由 + TLS over TLS)
Nginx 不解密流量,仅读取 ClientHello 中的 SNI 或 ALPN 字段做路由,并作为 TLS 客户端重连上游,实现端到端加密保障:
- 启用 ssl_preread on,配合 map 指令按域名分发
- 使用 proxy_ssl on 及相关指令(如 proxy_ssl_trusted_certificate、proxy_ssl_verify)建立可信 TLS 隧道
- 典型场景:多租户共用 443 端口,或 gRPC/HTTPS/MQTT over TLS 的协议识别分流
提升稳定性和安全性的关键配置
仅开启 TLS 不代表高可用。以下参数直接影响隧道质量:
- proxy_timeout:建议设为业务最大空闲等待时间(如 30s~1h),避免连接被意外中断
- proxy_responses 1:对请求-响应型协议(如 PostgreSQL、Redis AUTH)可防止粘包误判
- proxy_ssl_protocols 和 proxy_ssl_ciphers:显式限定 TLS 版本与密码套件,禁用弱算法(如 TLSv1.0、RC4、MD5)
- proxy_ssl_verify on + proxy_ssl_trusted_certificate:校验上游证书有效性,防止中间人劫持
验证与调试建议
上线前务必实测 TLS 握手行为:
- 用 openssl s_client -connect your-nginx:port -servername example.com 检查 SNI 是否被正确识别
- 抓包观察 ClientHello 是否含预期 SNI,ServerHello 是否由目标后端返回(而非 Nginx 自签)
- 检查 Nginx error.log 中是否有 “SSL_do_handshake() failed” 或 “certificate verify failed” 类报错
- 对 mTLS 场景,补充配置 ssl_client_certificate 和 ssl_verify_client on



















