如何正确使用SNI:两种Nginx SNI不同配置写法的差异对比
两种Nginx SNI配置的差异分析
两种配置都是实现多域名同端口SNI复用的方案,但实现逻辑、适用场景、性能表现差异极大,以下分维度说明:
实现原理差异
- 写法1(stream + ssl_preread方案):基于Nginx四层
stream模块的ssl_preread特性实现,在TCP握手后的SSL握手阶段,不需要解密流量,直接读取SSL报文里的SNI字段,根据预先配置的映射规则把整个TCP连接转发到对应后端端口(或后端服务器),后续的SSL解密、HTTP请求处理都由对应端口的七层http模块server块完成,属于「四层预分流+七层业务处理」的两层架构。 - 写法2(原生http模块SNI方案):是Nginx标准的七层SNI实现,所有域名的流量都统一进入443端口,Nginx在七层SSL握手阶段直接读取SNI字段,匹配对应
server_name的server块,调用该块下配置的证书完成SSL解密,后续直接处理HTTP请求,全程都在http模块内完成,没有额外的转发环节。
功能特性差异
- 写法1的优势:
- 不限制上层协议,除了HTTP/HTTPS之外,还可以转发WebSocket、gRPC甚至非HTTP的TCP服务(如MySQL、SSH等支持SNI的TCP协议)
- 分流阶段不需要处理证书,证书可以部署在后端业务服务上,适合证书分散管理、不想把证书放在入口网关的场景
- 支持跨机器转发流量,可作为多节点集群的统一四层SNI入口网关
- 写法2的优势:
- 配置简单,不需要编译
stream和ssl_preread模块,绝大多数默认编译的Nginx都直接支持,也不需要额外占用多个监听端口 - 支持同一端口下的HTTP/2、HTTP/3多路复用特性,同一个TCP连接下的多个请求可以复用SSL握手结果
- 可统一配置全局七层策略,比如统一的访问日志、WAF拦截、限速限流、跳转规则等
- 配置简单,不需要编译
- 各自局限性:
- 写法1需要Nginx编译时开启
stream和ssl_preread模块,部分发行版默认Nginx不支持,同时需要为不同业务分配独立的后端监听端口,配置维护成本更高 - 写法2仅支持HTTP/HTTPS协议,无法处理非HTTP的TCP流量,证书必须统一部署在入口Nginx上,不支持证书下沉到业务侧的场景
- 写法1需要Nginx编译时开启
性能表现差异
- 同机部署场景下,写法2性能远高于写法1:写法1多了一次四层到七层的端口转发流程,每个连接需要经过两次Nginx的处理链路,CPU、内存开销都更高,高并发下的转发延迟会明显上升;同时不同域名走不同端口,无法复用SSL会话,重复SSL握手的概率更高,进一步拉高CPU开销。写法2没有额外转发开销,同端口下SSL会话可复用,性能损耗极低。
- 跨机器转发场景下,写法1性能优于七层反向代理:如果写法1的后端是其他机器的服务,不需要在入口端解密流量,仅做四层转发的CPU开销远低于七层卸载证书再反向代理的开销,性能表现更好。
适用场景差异
- 写法1适合:多协议混合的入口网关、需要跨机器转发SNI流量、证书需要下沉到业务服务、需要透明代理TCP流量的场景
- 写法2适合:纯HTTP/HTTPS业务、单节点部署多域名站点、需要统一管理七层策略的常规业务场景
内容的提问来源于stack exchange,提问作者gricn
相关产品推荐
相关产品推荐

