NGINX 四层 SSL/TLS 支持ngx_stream_ssl_module
一、模块概述
ngx_stream_ssl_module
自 NGINX 1.9.0(2015-08-04)起,为四层(TCP/UDP)代理增添完整的 SSL/TLS 能力。它依赖 OpenSSL 库,必须在编译时加上 --with-stream_ssl_module
(若已启用 --with-stream
,通常一并包含)。
启用此模块后,你可以在 stream { server { … } }
语境下使用二十余条指令,实现:
- 证书与私钥加载(支持变量、
data:
、多种类型证书) - TLS 协议版本与密码套件控制
- 会话缓存(共享与内建)、会话票据与轮换
- 客户端证书验证、CRL/OCSP 检查与缓存
- ALPN 多协议协商与分流
- 双向 TLS(mTLS)与握手调优
- 调试日志(SSLKEYLOGFILE 兼容 Wireshark)
二、编译与基本配置
# 源码编译时确保包含
./configure … --with-stream --with-stream_ssl_module …
make && make install
在配置文件中,通常在全局设置:
worker_processes auto; # 建议与 CPU 核心数一致
然后在 stream
块中为某个端口开启 SSL:
stream {server {listen 12345 ssl; # TCP 四层监听并开启 TLS# 以下配置详见下一节}
}
三、核心指令详解
1. 证书与私钥
-
ssl_certificate
指定 PEM 格式证书文件(可多次声明加载 RSA/ECDSA)。 -
ssl_certificate_key
指定 PEM 私钥文件。 -
ssl_certificate_cache
(1.27.4+)
为变量加载的证书与私钥启用内存缓存:ssl_certificate $ssl_server_name.crt; ssl_certificate_key $ssl_server_name.key; ssl_certificate_cache max=1000 inactive=20s valid=1m;
2. 协议与密码套件
ssl_protocols TLSv1.2 TLSv1.3
推荐仅启用 TLSv1.2/1.3。ssl_ciphers
OpenSSL 格式密码列表,例如HIGH:!aNULL:!MD5
。ssl_prefer_server_ciphers on;
服务端优先选择密码套件。ssl_alpn h2 http/1.1;
(1.21.4+)
ALPN 协商 HTTP/2 与 HTTP/1.1,可结合map $ssl_alpn_protocol
动态分流。
3. 会话管理
-
ssl_session_cache
builtin:1000
(内建缓存)shared:SSL:10m
(多 worker 共享)
-
ssl_session_tickets on;
开启会话票据。 -
ssl_session_ticket_key
指定一个或多个文件,实现 Key 轮换。 -
ssl_session_timeout 10m;
指定会话有效期(默认 5 分钟)。
4. 客户端认证与 OCSP/CRL
ssl_verify_client on|off|optional|optional_no_ca;
控制是否强制双向 TLS。ssl_client_certificate
&ssl_trusted_certificate
指定 CA 证书链,用于验证客户端证书与 OCSP。ssl_crl /path/to/crl.pem;
加载吊销列表。ssl_stapling on; ssl_ocsp_responder http://...; ssl_ocsp_cache shared:OCSP:10m; ssl_stapling_verify on;
(1.27.2+)
启用 OCSP 在线验证并缓存,确保证书未被吊销。
5. 性能与调试
ssl_dhparam /etc/ssl/dhparam.pem;
自定义 DHE 参数。ssl_ecdh_curve prime256v1:secp384r1;
指定 ECDHE 曲线列表。ssl_handshake_timeout 60s;
握手超时,防止长连接耗尽资源。ssl_key_log /var/log/sslkeys.log;
(1.27.2+ 商业版)
输出 SSLKEYLOGFILE,供 Wireshark 解码。
四、配置示例:多协议分流
worker_processes auto;stream {# 根据 ALPN 协议分流到不同上游map $ssl_alpn_protocol $backend {h2 127.0.0.1:8443;http/1.1 127.0.0.1:8080;default 127.0.0.1:8080;}server {listen 443 ssl;ssl_certificate /etc/nginx/ssl/server.pem;ssl_certificate_key /etc/nginx/ssl/server.key;ssl_protocols TLSv1.2 TLSv1.3;ssl_ciphers HIGH:!aNULL:!MD5;ssl_alpn h2 http/1.1;ssl_session_cache shared:SSL:20m;ssl_session_timeout 15m;proxy_pass $backend;}
}
- 客户端握手时通过 ALPN 协议选择,NGINX 终结 TLS 后将连接零拷贝交给对应后端,省去二次解密开销。
五、内置变量支持
模块自 1.11.2 起支持多种 SSL 相关变量,常用的包括:
$ssl_protocol
:当前连接使用的协议$ssl_cipher
:协商出的密码套件$ssl_alpn_protocol
:ALPN 协商结果$ssl_session_reused
:会话是否重用$ssl_client_verify
:客户端证书验证结果
结合这些变量,可在 access_log
、map
、if
等指令中灵活引用。
六、实战优化与注意事项
- 共享缓存优先:仅使用
shared:SSL
缓存比内建更节省内存碎片。 - 会话票据轮换:配置多个
ssl_session_ticket_key
,实现无缝平滑切换。 - 最小协议矩阵:关闭所有弱协议与弱 ciphers,保证安全兼容。
- OCSP/CRL 并用:对高安全场景同时启用 CRL 与 OCSP 可提升吊销检测覆盖率。
- 变量加载证书慎用:若用
$ssl_server_name
变量加载证书,建议开启ssl_certificate_cache
减少 I/O。
七、总结
ngx_stream_ssl_module
让 NGINX 在 TCP/UDP 四层代理层面也能享有与 HTTP 相同的 SSL/TLS 能力。通过灵活的证书管理、会话优化、客户端认证与 OCSP 验证,以及多协议分流,能构建高性能、高安全性的底层加密隧道。升级到 NGINX ≥1.9.0,并在源码编译时加上 --with-stream_ssl_module
,即可轻松开启这一强大模块。
立即实战:结合你的应用场景,挑选合适指令与缓存策略,让底层流量在安全与性能之间取得最佳平衡!