Nginx 与代理服务共用 443 端口的几种方案小结

网络Nginx 发布于 2026-08-27 · 分类:网络协议 · 阅读 3,284

一台服务器上同时要跑网站和 TLS 代理时,会遇到一个很现实的问题:443 端口只有一个,TCP 层面同一个端口只能被一个进程绑定。下面小结两种常见的共存思路。

方案一:应用层 fallback(回落)

让代理程序自己监听 443 并持有 TLS 证书。它在完成 TLS 握手后检查对端发来的第一段数据:如果是合法的代理协议且认证通过,就走代理;否则把这条连接原样转发给本机真正的 Web 服务。

"ssl": {
    "cert": "/etc/xxx/cert.pem",
    "key":  "/etc/xxx/private.key",
    "sni":  "example.com",
    "fallback_addr": "127.0.0.1",
    "fallback_port": 80
}

这样浏览器或主动探测者访问 https://example.com/ 时,看到的是一个证书有效、内容正常的真实网站;真正的客户端带正确口令连接时则走代理通道。

关键点:443 的监听者始终只有代理程序一个,Nginx 并不直接监听公网 443,它只是背后的「伪装网站」。

方案二:Nginx stream + ssl_preread 按 SNI 分流

另一种做法是让 Nginx 占 443,但不解密流量,而是在 ClientHello 里读取明文 SNI(域名),按域名做四层转发:

stream {
    map $ssl_preread_server_name $upstream {
        proxy.example.com   trojan_backend;
        default             web_backend;
    }
    server {
        listen 443;
        ssl_preread on;
        proxy_pass $upstream;
    }
}

优点是多个 HTTPS 站点和代理可共用一个 443、各持各的证书;代价是配置更复杂,且分流只依据 SNI。

如何选择

排查小贴士

改完后建议从外部验证三件事:curl https://域名/ 能返回正常网页、证书链有效、代理端口仍可正常使用。用 ss -tlnp 确认 443 的监听者到底是谁,可以避免「以为两个程序都在用 443」的误解。

— 本文为个人运维笔记,如有疏漏欢迎指正。