导读:本期聚焦于新井创作的《Nginx ngx_stream_ssl_module流SSL加密怎么配置?四层代理TLS实战详解》,敬请观看详情。为什么Nginx的四层代理在转发数据库、Redis等非HTTP流量时需要单独配置SSL?答案就藏在ngx_stream_ssl_module这个模块里。它工作在传输层,与大家熟悉的HTTP层SSL配置有明显区别,证书加载方式、协议版本控制、会话复用等参数都有自己的一套写法。本文将带你从模块原理讲起,逐步演示如何在stream块中加载证书、开启TLSv1.2和TLSv1.3、配置客户端证书校验实现双向认证,并结合proxy_ssl参数对接上游加密服务。同时还会对比stream SSL与http SSL的配置差异,分析常见报错原因和性能调优技巧,帮你把TCP代理的加密链路一次配通。

Nginx做反向代理时,大部分人熟悉的是七层的http模块配SSL,也就是通过listen 443 ssl加ssl_certificate指令给网站加HTTPS。但如果要代理的是MySQL、Redis、Kafka这类基于TCP的自定义协议,七层模块就无能为力了,这时候需要stream模块在四层做转发。而四层流量同样可能需要加密,ngx_stream_ssl_module就是专门负责这件事的模块。它提供了一套与http层相似但不完全相同的SSL指令集,支持服务端证书、双向认证、协议版本控制、会话缓存等能力。

Nginx ngx_stream_ssl_module流SSL加密怎么配置?四层代理TLS实战详解

一、模块原理与编译加载方式

ngx_stream_ssl_module并不是默认编译进Nginx的模块。如果你使用的是官方发布的源码包自行编译,需要在configure阶段显式加上--with-stream_ssl_module参数,同时还依赖--with-stream这个基础模块。完整的编译参数示例如下:

./configure --with-stream --with-stream_ssl_module \
    --with-http_ssl_module \
    --with-openssl=/usr/local/src/openssl-3.0.0
make && make install

编译完成后,可以通过nginx -V查看已有的编译参数,确认输出中包含stream_ssl_module字样。如果使用的是各大Linux发行版的Nginx包,例如通过apt或yum安装的nginx,一般会以动态模块形式提供,检查/usr/lib/nginx/modules目录下是否存在ngx_stream_ssl_module.so即可。若是以动态模块方式加载,需要在nginx.conf最顶部使用load_module指令引入,注意这条指令必须写在所有其他指令之前。

从工作原理上看,stream层的SSL终结发生在TCP连接建立之后、数据转发之前。客户端发起TCP握手,Nginx完成SSL握手后,如果配置了ssl参数,后续的报文会被解密再转发给上游。这和LVS这类纯四层转发有本质区别,Nginx在四层代理中依然可以理解TLS协议本身,只是不理解TLS载荷里的应用层协议内容。

二、基础配置:在stream块中启用SSL

stream模块的配置必须写在http块之外、与http块平级的stream块中。一个最基础的服务端SSL配置如下:

stream {
    upstream mysql_backend {
        server 192.168.1.10:3306;
        server 192.168.1.11:3306;
    }

    server {
        listen 3306 ssl;               # ssl参数表示该端口启用TLS
        proxy_pass mysql_backend;

        # 证书配置
        ssl_certificate        /etc/nginx/certs/server.pem;
        ssl_certificate_key    /etc/nginx/certs/server.key;

        # 协议版本控制
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;
    }
}

有几个细节需要注意。第一,listen指令后的ssl参数是开关,没有它证书配置不会生效,客户端用普通TCP连接也能进来,这是新手最常踩的坑之一。第二,证书路径建议使用PEM格式,如果私钥有密码,Nginx启动时会交互式询问,生产环境通常用无密码私钥配合文件权限管理。第三,ssl_session_cache设置为shared模式可以在多个worker进程间共享会话,避免每个进程各自缓存导致命中率低下。

TLSv1.3相比TLSv1.2在握手性能上有明显优势,1-RTT甚至0-RTT的握手减少了往返次数,对四层长连接场景帮助很大。但如果客户端软件较老,比如某些嵌入式设备只支持TLSv1.0,就要谨慎裁剪ssl_protocols列表,在安全性和兼容性之间做权衡。

三、进阶:客户端证书校验与上游加密

单向TLS只验证服务端身份,如果业务要求客户端也必须证明自己是合法的,比如内网数据库代理只允许特定应用服务器连接,就需要开启双向认证。stream模块同样支持ssl_verify_client指令:

server {
    listen 6379 ssl;
    proxy_pass redis_backend;

    ssl_certificate        /etc/nginx/certs/server.pem;
    ssl_certificate_key    /etc/nginx/certs/server.key;

    # 双向认证配置
    ssl_client_certificate /etc/nginx/certs/ca.pem;
    ssl_verify_client on;
    ssl_verify_depth 2;
}

配置后,客户端连接时必须携带由指定CA签发的证书,否则SSL握手阶段就会被拒绝,连TCP层面的数据都不会传输。这在安全上是好事,握手即失败,不会暴露任何应用层信息。需要注意的是,ssl_client_certificate指向的是CA证书而非客户端证书本身,验证的是证书链的信任关系。

另一个常见需求是Nginx作为SSL终结点后,与上游服务器之间的链路也要加密。这时需要用到proxy_ssl系列指令,这部分属于ngx_stream_proxy_module,但与SSL配置紧密相关:

server {
    listen 443 ssl;
    proxy_pass kafka_backend:9093;

    ssl_certificate     /etc/nginx/certs/server.pem;
    ssl_certificate_key /etc/nginx/certs/server.key;

    # 到上游的连接也走TLS
    proxy_ssl on;
    proxy_ssl_certificate     /etc/nginx/certs/client.pem;
    proxy_ssl_certificate_key /etc/nginx/certs/client.key;
    proxy_ssl_trusted_certificate /etc/nginx/certs/upstream-ca.pem;
    proxy_ssl_verify on;
    proxy_ssl_server_name on;
}

这样就形成了一条客户端到Nginx、Nginx到上游的双重加密链路。如果上游是自签名证书,要么把证书加入信任列表,要么临时关闭proxy_ssl_verify,但生产环境强烈不建议关闭验证,中间人攻击的风险不可忽视。

四、常见报错排查与性能调优

配置完成后,排错是绕不开的环节。最典型的报错是no ssl_certificate is defined,说明server块里加了ssl参数却忘了配证书。另一个是握手失败时日志里出现SSL_do_handshake() failed,常见原因包括协议版本不匹配、密码套件不支持、客户端证书过期等。排查时建议把error_log的级别调到debug,配合openssl s_client -connect host:port命令从客户端侧模拟握手,能快速定位问题出在哪一步。

性能方面有几点值得优化。会话复用方面,除了前面提到的shared缓存,TLSv1.3默认支持会话票据,可以进一步减少握手开销。硬件层面,如果流量很大,确认Nginx链接的是支持硬件加速的OpenSSL版本,AES-NI指令集能显著降低加解密CPU占用。另外,ssl_handshake_timeout默认60秒偏长,公网环境建议缩短到10秒左右,防止恶意慢速握手拖垮连接资源。还可以通过ssl_session_tickets和定期轮换证书密钥来平衡性能与安全性。最后提醒一点,修改stream相关配置后用nginx -t测试语法再reload,因为stream块配置错误同样会导致reload失败,影响整个Nginx服务的平滑运行。

Nginxngx_stream_ssl_module流SSL加密修改时间:2026-09-16 18:00:46

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/0916/58098.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。