【HAProxy 数据面】SSL/TLS 路径:终结与透传、握手落点与会话缓存

💡 原文中文,约6600字,阅读约需16分钟。
📝

内容提要

本文介绍HAProxy中SSL/TLS的两种处理路径:终结(在HAProxy内完成握手)与透传(仅转发字节,上游处理)。握手CPU消耗落在接收连接的线程上,会话缓存(tune.ssl.cachesize)影响全握手频率。证书选择与ALPN在握手期决定,与HTTP层ACL无关。容量规划需考虑缓存预分配内存,区分全握手与会话恢复的成本差异。

🔎

延伸解读

终结与透传:先分清谁做握手

配置中是否启用 bind ssl 以及 mode http/tcp,决定了 HAProxy 能否看到 HTTP 内容。透传模式下,HAProxy 只转发字节,握手在上游完成,无法基于 Host 头做内容交换;终结模式则在 HAProxy 内完成握手,之后才能进行 L7 处理。理解这一区别,有助于避免将 SSL 农场与终结混为一谈。

握手线程亲和:CPU 成本落在哪

TLS 握手是重 CPU 操作,且发生在接受连接的线程上,不会自动迁移到空闲线程。因此,大量全握手会抬高该线程上其他会话的延迟。排障时,若发现某线程 CPU 高,需考虑是否因握手集中所致,而非简单归咎于全局锁。

会话缓存:预分配内存与全握手权衡

tune.ssl.cachesize 预分配内存块,缓存满时驱逐最空闲项,增大缓存可减少全握手次数,但需权衡常驻内存。关闭缓存或使用私有缓存(多进程下)会导致重复握手,增加 CPU 开销。容量规划时,应将缓存预分配计入内存,并区分全握手与会话恢复的成本差异。

证书选择与 ALPN:握手期决策,非 HTTP 层

证书选择依据 SNI 在握手阶段完成,早于 HTTP ACL;ALPN 协商也发生在握手期,影响后续协议(如 H2)。因此,不能将 Host 头 ACL 误认为选证机制。若 SNI 与证书不匹配,可能导致握手失败或使用默认证书,而非事后改写。

Q&A

HAProxy中SSL/TLS终结和透传有什么区别?

SSL/TLS终结是指在HAProxy内完成TLS握手,之后处理明文HTTP,可以进行ACL、HTX等L7操作;透传是指HAProxy仅转发TCP字节,TLS握手在上游服务器完成,HAProxy无法看到HTTP内容。

HAProxy中TLS握手消耗的CPU资源落在哪个线程上?

TLS握手消耗的CPU资源落在接受该连接的线程上,因为会话实体钉在接受连接的线程上,握手不会自动被空闲线程池偷走。

tune.ssl.cachesize参数的作用是什么?

tune.ssl.cachesize设置全局SSL会话缓存的块数,默认20000块,每块约200字节。缓存用于存储会话,减少完整握手次数。缓存满时驱逐最空闲项,更大的缓存降低驱逐,从而减少昂贵的完整握手。设为0则关闭会话缓存。

HAProxy中证书选择是基于什么决定的?

证书选择在TLS握手阶段基于客户端SNI(Server Name Indication)决定,早于HTTP ACL。如果SNI缺失或不匹配,则使用默认证书或握手失败,不能通过Host头事后更改。

HAProxy中ALPN协商的作用是什么?

ALPN(应用层协议协商)在TLS握手期间决定后续使用的协议,如HTTP/2或HTTP/1.1。协商结果影响是否使用H2多路复用、连接复用键以及健康检查中的alpn参数。

HAProxy中透传模式下健康检查和粘滞有什么限制?

透传模式下,HAProxy只能基于TCP/IP层信息或外部元数据(如PROXY头)进行决策,不能基于加密的HTTP内容。健康检查使用独立的握手(如http-check connect ssl sni),与客户连接的会话缓存无关。粘滞若依赖SSL ID,在透传模式下无法看到明文ID,除非在别处学习。

🏷️

标签

➡️

继续阅读