零星笔记

用 nginx stream 做 SNI 分流

2026-08-02 · 运维

一台机器只有一个 443 端口,但上面想跑好几个互相无关的 TLS 服务。stream 模块的 ssl_preread 就是干这个的。

原理

它只把 ClientHello 里明文的 SNI 字段读出来,不解密、不终止 TLS,然后按 map 把整条 TCP 连接转给对应的后端。所以带宽开销基本等于一次内存拷贝,延迟增加在微秒级。

stream {
    map $ssl_preread_server_name $backend {
        a.example.com  127.0.0.1:9443;
        b.example.com  127.0.0.1:9444;
        default        127.0.0.1:9445;
    }
    server {
        listen 443;
        proxy_pass $backend;
        ssl_preread on;
    }
}

几个实际问题

和 http 层的区别

listen 443 ssl 是 nginx 自己终止 TLS;stream 是原样转发,TLS 在后面的服务里终止。两者不冲突,但同一个端口只能二选一。