TLS 代理:从终止、透传到中间人拦截的完整指南
当你部署一个 Web 服务并配上 HTTPS 之后,下一个几乎必然遇到的需求就是 TLS 代理——让一个中间节点替你处理加密、路由、甚至检查加密流量本身。这件事听起来简单,背后却藏着至少四种完全不同的工作模式、一套精巧的 SNI 路由机制,以及 TLS 1.3 引入 ECH 后正在发生的范式转移。
本文从 TLS 代理的三种基本角色出发,逐一拆解每种模式的工作原理、典型配置和适用场景,最后讨论 ECH 对代理生态的冲击。
1. 先分清三种角色:正向代理、反向代理与 TLS 代理
在讨论 TLS 代理之前,必须先把"代理"这个词的两层方向性讲清楚,否则后面的内容很容易混淆。
- 正向代理(Forward Proxy)站在客户端一侧。客户端知道自己要通过代理访问外部服务器,代理对服务器隐藏了客户端的真实 IP。典型场景是企业出口网关、科学上网工具。
- 反向代理(Reverse Proxy)站在服务端一侧。客户端以为自己直接访问目标服务器,实际上请求先到达反向代理,再由代理转发给后端。典型场景是 CDN、负载均衡器、API 网关。
- TLS 代理是在上述代理的基础上,增加了对 TLS 流量的特殊处理能力——它可以终止 TLS、透传 TLS,甚至主动解密并检查 TLS 流量[1]。
下面的 Mermaid 图展示了正向代理和反向代理在网络拓扑中的位置差异:
在这个框架下,TLS 代理根据是否解密 TLS 流量以及解密后如何处理,可以细分为四种模式。下面逐一展开。
2. 四种 TLS 代理模式
2.1 TLS 终止代理(TLS Termination Proxy)
TLS 终止代理是最常见的反向代理模式。代理持有服务端的有效 TLS 证书,在代理处完成 TLS 握手并解密流量,然后将明文请求转发给后端服务器[1:1]。
这种模式有三大优势:
- 集中式证书管理:只需在代理上维护证书,后端服务器不需要关心 TLS。
- 计算卸载(SSL Offloading):将非对称加密的计算压力从业务服务器转移到专用代理节点。
- 内容感知路由:代理可以看到完整的 HTTP 头部和正文,据此做缓存、压缩、WAF 防护、A/B 测试等[2]。
Nginx 典型配置:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/certs/example.com.pem;
ssl_certificate_key /etc/nginx/certs/example.com.key;
location / {
proxy_pass http://backend:8080;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}2.2 TLS 桥接代理(TLS Bridging Proxy)
TLS 桥接是终止模式的升级版。代理在解密客户端请求后,重新加密再转发给后端。也就是说,代理和后端之间也走 TLS[1:2]。
这种模式适用于零信任网络架构——即使代理和后端在同一个数据中心内,也不允许明文传输敏感数据。它需要代理和后端各自持有证书,通常使用内部 CA 签发的证书。
2.3 TLS 透传代理(TLS Passthrough Proxy)
透传代理完全不解密 TLS 流量,只根据 TLS 握手中的明文信息(主要是 SNI)决定将流量转发给哪个后端[3]。
这种模式的核心依赖是 SNI(服务器名称指示,Server Name Indication),它出现在 TLS ClientHello 的明文部分。代理只需要解析 ClientHello 的前几个字节提取 SNI,然后像 TCP 代理一样转发整个连接。
它的优缺点很鲜明:
- 优点:后端拥有完整的 TLS 控制权;不需要在代理上管理证书;隐私性好。
- 缺点:代理无法看到 HTTP 内容,不能做缓存、WAF、基于 URL 的路由等七层操作;无法在一个端口上混合 HTTP 和 HTTPS 路由。
HAProxy 典型配置:
frontend ft_https
bind :443
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend bk_app1 if { req_ssl_sni -i app1.example.com }
use_backend bk_app2 if { req_ssl_sni -i app2.example.com }
default_backend bk_default
backend bk_app1
mode tcp
server srv1 10.0.1.10:443 check
backend bk_app2
mode tcp
server srv2 10.0.1.20:443 checkKong 社区中有一个长期讨论就是关于透传模式——Kong 目前要么需要终止 TLS 才能拿到 SNI,要么只能按端口全量转发,做不到"只看 SNI 不解密"[4]。Nginx 从 1.9.0 起通过 ngx_stream_ssl_preread_module 模块支持 TLS 透传:
stream {
map $ssl_preread_server_name $backend {
app1.example.com backend1:443;
app2.example.com backend2:443;
default backend_default:443;
}
server {
listen 443;
proxy_pass $backend;
ssl_preread on;
}
}2.4 TLS 正向代理 / MITM 拦截代理
前三种模式都是反向代理场景。但企业网络还需要另一种能力:对员工发出的 HTTPS 流量进行检查,防止数据泄露、恶意软件通信或违反合规要求。这就需要 TLS 正向代理,即中间人拦截代理(MITM Proxy)。
它的工作原理是"合法化的中间人攻击"[5]:
- 企业 IT 在员工设备上预装一个私有 CA 根证书。
- 当客户端通过代理访问
https://example.com时,代理代替客户端与目标服务器建立 TLS 连接。 - 代理用自己的私有 CA 为
example.com实时签发一张假证书,并用这张证书与客户端完成 TLS 握手。 - 客户端因为信任了私有 CA,不会收到证书警告。
- 代理在中间解密、检查、记录流量,甚至修改内容。
Squid SSL Bump 配置示例[6]:
# 生成 CA 证书
openssl req -new -newkey rsa:4096 -sha256 -days 3650 -noenc -x509 \
-subj "/C=US/O=Corporate CA/CN=Squid Proxy CA" \
-addext "basicConstraints=critical,CA:TRUE" \
-addext "keyUsage=critical,keyCertSign,cRLSign" \
-keyout /etc/squid/ssl/squid.key \
-out /etc/squid/ssl/squid.crt
# 合并为 PEM
cat /etc/squid/ssl/squid.crt /etc/squid/ssl/squid.key > /etc/squid/ssl/squid.pem
# squid.conf
http_port 3128 ssl-bump \
tls-cert=/etc/squid/ssl/squid.pem \
generate-host-certificates=on \
dynamic_cert_mem_cache_size=4MB
sslcrtd_program /usr/lib/squid/security_file_certgen \
-s /var/lib/squid/ssl_db -M 4MB
acl step1 at_step SslBump1
acl step2 at_step SslBump2
acl step3 at_step SslBump3
# 不拦截的敏感站点(银行、医疗等)
acl no_bump ssl::server_name .bank.com .healthcare.gov
ssl_bump splice no_bump
ssl_bump peek step1
ssl_bump stare step2
ssl_bump bump step3重要提醒:MITM 代理本质上破坏了 TLS 的端到端安全模型。它必须在所有客户端设备上安装私有 CA 根证书,且这个根证书的私钥一旦泄露,攻击者就可以对信任该 CA 的任何设备发起真正的中间人攻击[7]。因此,私有 CA 的私钥保护是整个方案中最关键的安全环节。
3. 核心协议机制:SNI、CONNECT 与动态证书
3.1 SNI——TLS 代理的"明信片"
SNI 是 TLS 扩展中定义的一个字段(RFC 6066),在 ClientHello 中以明文形式传输。它的设计初衷是解决一个实际问题:一个 IP 地址上托管了多个 HTTPS 站点,服务器需要在看到加密的 HTTP 请求之前就知道该用哪个证书完成握手。
对 TLS 代理而言,SNI 是透传模式下唯一可用的路由信息。没有 SNI,透传代理只能把所有 443 端口的流量转发到同一个后端,或使用不同的 IP 地址区分站点[3:1]。
3.2 HTTP CONNECT 隧道
正向代理处理 HTTPS 的标准方式是 HTTP CONNECT 方法(RFC 7231)。客户端向代理发送:
CONNECT example.com:443 HTTP/1.1
Host: example.com:443代理建立到目标服务器的 TCP 连接后,返回 200 Connection Established。此后,代理在客户端和服务器之间盲转发 TCP 字节流,不解析 TLS 内容[5:1]。
这就是"隧道模式"——代理只是一个字节管道,TLS 握手完全在客户端和目标服务器之间完成。如果要升级到 SSL Bump 模式(进行内容检查),代理需要在 CONNECT 之后主动介入 TLS 握手,这正是上一节 MITM 模式的工作。
3.3 动态证书生成
MITM 代理需要为每个访问的域名实时生成证书。Squid 使用 security_file_certgen 辅助程序来完成这件事——它会缓存已生成的证书以提高性能,并使用配置中的 CA 证书进行签名[7:1]。现代企业代理方案(如 Symantec / Broadcom 的 SSL Visibility Appliance)则将这个过程硬件加速,处理能力可达数十 Gbps。
4. 主流 TLS 代理实现对比
| 实现 | 终止 | 透传 | 桥接 | MITM | 特点 |
|---|---|---|---|---|---|
| Nginx | ✅ | ✅ (stream) | ✅ | ❌ | 生态最大,性能优秀 |
| HAProxy | ✅ | ✅ (SNI) | ✅ | ❌ | 七层处理能力极强,ACL 灵活 |
| Envoy | ✅ | ✅ (SNI) | ✅ | ❌ | 云原生首选,xDS 动态配置 |
| Traefik | ✅ | ✅ (TCP) | ✅ | ❌ | 自动发现,容器原生 |
| Squid | ✅ | ✅ | ✅ | ✅ | 唯一支持完整 MITM 的开源方案 |
| Caddy | ✅ | ❌ | ✅ | ❌ | 自动 HTTPS,配置简洁 |
5. 选型决策指南
选择哪种 TLS 代理模式,取决于你在回答三个问题:
- 代理需要看到 HTTP 内容吗? → 需要:终止/桥接/MITM;不需要:透传。
- 后端能接受明文流量吗? → 能:终止;不能(零信任要求):桥接。
- 代理是客户端出口还是服务端入口? → 客户端出口:正向代理 / MITM;服务端入口:反向代理(终止、桥接或透传)。
可以用以下决策流程图来辅助判断:
6. ECH:正在改写游戏规则
ECH(加密 Client Hello,Encrypted Client Hello)是 TLS 1.3 的一个扩展,它把整个 ClientHello——包括 SNI——都加密了[8][9]。这对隐私是好消息,但对 TLS 代理(尤其是透传代理和企业 MITM 代理)是根本性冲击。
6.1 ECH 的工作原理
ECH 引入了一个"外层 SNI"和一个"内层 SNI"。外层 SNI 指向一个"掩护域名"(如 Cloudflare 的 cloudflare-ech.com),真正的目标域名被加密在 ClientHello 的扩展中。只有拥有对应私钥的服务器才能解密内层 SNI[8:1]。
6.2 对代理生态的影响
ECH 在 2024—2026 年间已经从实验性功能走向大规模部署。根据 FOCI 2025 的研究,俄罗斯的 TSPU 设备在 2025 年 3 月已经开始主动丢弃包含 ECH 扩展的 ClientHello[10]。而企业安全领域面临的挑战更为根本[11]:
- 透传代理失效:无法读取 SNI,意味着无法做基于域名的路由。
- MITM 代理需要主动解密 ECH:代理必须在 ClientHello 阶段介入,用自己的密钥解密 ECH,这进一步复杂化了代理的实现。
- 流量分类与 DLP 系统盲化:传统的基于 SNI 或证书 CN 的流量识别手段全面失效,企业必须转向端点级别的检测方案。
Enea 在 2025 年的报告中指出,TLS 1.3 ECH 将迫使网络安全从"基础设施层"转向"应用层",QUIC 和 HTTP/3 的普及进一步加速了这一趋势[12]。
6.3 应对策略
面对 ECH,企业有以下可选路径:
- 在企业网关上同时部署 MITM 代理——代理主动参与 ECH 解密。代价是计算开销显著增加,且需要维护更复杂的证书体系。
- 转向端点检测与响应(EDR)方案——放弃在网络层做流量检查,转而在终端设备上做行为监控。
- 使用基于 DNS 的策略控制——在 ECH 部署之前,企业 DNS 解析器仍然能看到用户请求的域名。
- 等待标准化和中间盒友好方案——IETF 的 ECH 草案仍在对中间盒兼容性做讨论。
7. 总结
TLS 代理不是一个"单一功能",而是一个包含了多种相互冲突需求的技术谱系:
| 模式 | 代理看得到内容? | 需要代理持证? | 端到端加密? | 主要用途 |
|---|---|---|---|---|
| 终止 | 是 | 是(真实证书) | 否(代理-后端可明文) | Web 服务反向代理 |
| 桥接 | 是 | 是(两张证书) | 是(两段分别加密) | 零信任架构 |
| 透传 | 否 | 否 | 是 | 多域名路由、TCP 代理 |
| MITM | 是 | 是(私有 CA) | 否(代理在中途解密) | 企业流量检查 |
选择哪种模式,本质上是在安全性、可观测性和运维复杂度之间做权衡。ECH 的到来正在把天平推向"端到端加密"一侧,但企业安全需求又拉着天平往"可观测性"一侧走。理解这四种模式的工作原理,才能在新的技术浪潮中做出正确的架构决策。
参考文献
Wikipedia. TLS termination proxy. https://en.wikipedia.org/wiki/TLS_termination_proxy ↩︎ ↩︎ ↩︎
Kemp Technologies. Forward Proxy Vs. Reverse Proxy: Differences and Similarities. https://kemptechnologies.com/blog/forward-proxy-vs.-reverse-proxy-differences-and-similarities ↩︎
Server Fault. How does a TLS Passthrough reverse proxy based on SNI work? https://serverfault.com/questions/1106141/how-does-a-tls-passthrough-reverse-proxy-based-on-sni-work ↩︎ ↩︎
Kong GitHub Discussions #7307. Support SNI-based routing without TLS termination. https://github.com/Kong/kong/discussions/7307 ↩︎
Eli Bendersky. Go and Proxy Servers: Part 2 - HTTPS Proxies (2022). https://eli.thegreenplace.net/2022/go-and-proxy-servers-part-2-https-proxies ↩︎ ↩︎
OneUptime Blog. How to Configure Squid SSL Bump for HTTPS Interception on IPv4 (2026). https://oneuptime.com/blog/post/2026-03-20-squid-ssl-bump-https-ipv4/view ↩︎
Squid Web Cache Wiki. Dynamic SSL Certificate Generation. https://wiki.squid-cache.org/Features/DynamicSslCert ↩︎ ↩︎
Cloudflare Blog. Good-bye ESNI, hello ECH! https://blog.cloudflare.com/encrypted-client-hello ↩︎ ↩︎
E. Rescorla, K. Oku, N. Sullivan, C. A. Wood. TLS Encrypted Client Hello (2025). Internet-Draft draft-ietf-tls-esni-24. IETF. ↩︎
FOCI 2025. Encrypted Client Hello (ECH) in Censorship Circumvention. https://petsymposium.org/foci/2025/foci-2025-0016.pdf ↩︎
SECURITY.COM. Navigating Encrypted Client Hello (ECH): Insights from RSAC 2025. https://www.security.com/expert-perspectives/navigating-encrypted-client-hello-ech-insights-rsac-2025 ↩︎
Enea. TLS 1.3 ECH - How to Preserve Visibility into Encrypted Traffic. https://www.enea.com/insights/tls-1-3-ech-how-to-preserve-critical-traffic-visibility-for-enterprise-and-network-security-while-safeguarding-privacy ↩︎