Nginx 配置:基于 SNI 的分流
出于某些考虑,我需要在后端来处理 TLS 握手——因此 Nginx 传统意义上的反向代理在此场景下是行不通的,必须在 TCP 层面进行流量转发。
Server Name Indication (SNI) is an extension to the Transport Layer Security (TLS) computer networking protocol by which a client indicates which hostname it is attempting to connect to at the start of the handshaking process.
Wikipedia
试想把 Nginx 作为服务器唯一的网关,所有基于 TCP/IP 协议的流量首先流入 Nginx,经过分流逻辑判断后转发到对应的内部服务端口上——
由此,部署在 443 端口的 Nginx 便可以作为服务器唯一的入口来统一管理和记录所有入站流量。
stream 在 443 端口进行分流
已知问题:会使后端 log 的源 IP 为 127.0.0.1,可以用 proxy_mode 解决?(待研究
在此处列出所有可接受的域名 ,未接受的域名可以有两种处理方式:
- 拒绝握手(推荐,仅 1.19.4 版本以上)
- 以 Plain HTTP 返回 400 Bad Request
1 | stream { |
此处会预读取 TLS 握手请求中的 SNI,与预设逻辑进行匹配,并将 TCP 流量完整地转发给任意端口
TCP 转发由 Nginx 的 ngx_stream_module
实现
加载静态mod
如果你的版本不能使用ssl_preread on
则需要先将静态 mod 加载进来,即在 Nginx 配置文件加上:
1 | load_module /usr/lib/nginx/modules/ngx_stream_module.so; |