用 ssl_preread 做 443 的 SNI 分流

2026-11-08 · 运维

一台机器只有一个 443,但想同时跑网站和别的 TLS 服务时,可以在 stream 层按 SNI 分发,不需要改动 HTTP 层的配置。

stream {
    map $ssl_preread_server_name $backend {
        example.com  127.0.0.1:8443;
        default      127.0.0.1:4443;
    }
    server {
        listen 443;
        proxy_pass $backend;
        ssl_preread on;
    }
}

几个注意点:ssl_preread 只读取 ClientHello,不解密,所以后端仍是完整的 TLS 端点;如果没有开启 preread,$ssl_preread_server_name 会是空的,全部落到 default。

另外 Ubuntu 上的 stream 模块需要单独装 libnginx-mod-stream,装完 nginx -t 会提示模块已加载,不用手工改 nginx.conf 的 load_module。