摘要
- ALPN 把应用协议选择放进 TLS 握手,省去另一次往返;客户端提交有顺序的候选,服务器只能从共同集合里选出一个。
- 没有共同协议时,正确结果是致命的
no_application_protocol,而不是悄悄猜一种默认语法。选中的标识只约束本连接。 - TLS 会话票据可以帮助恢复密码学状态,却不能携带上一条连接的 ALPN 决定。TLS 1.3 保护了服务器回答,也没有让客户端候选、应用授权或部署事实自动获得保密与证明。
一张抓包为什么少了服务器的答案
运维人员比较两次连接。客户端发出的 ALPN 候选相同,服务端最终都使用 HTTP/2。较旧的 TLS 1.2 抓包能够直接看到服务端在 ServerHello 中返回的选择;TLS 1.3 抓包里,同一位置却没有那个值。
如果把“抓包中不可见”直接写成“服务器没有协商”,就会把协议演进误判成生产故障。相反,如果把“TLS 1.3 已加密服务器选择”扩大成“ALPN 已完全不可见”,又会遗漏普通 ClientHello 仍携带客户端候选的事实。
RFC 7301 最初有意识地把服务端选择放在当时的 ServerHello 里。共享端口以后,网络设备不能只靠 TCP 或 UDP 端口判断上层协议;一个可见标记便于按连接区分服务。规范同时提醒:客户端发送的协议名可能泄露敏感信息,设计新标识时不能把可见性当作无害条件。
TLS 1.3 的 RFC 8446 改变了服务端这一侧。ALPN 回答进入 EncryptedExtensions;这是服务端第一个使用握手流量密钥加密的消息。客户端候选仍位于 ClientHello。可见边界因版本与方向而异,而不是从“全明文”一步跳成“全秘密”。
443 已经不能说明后面由谁解析
传统端口号曾经是应用协议的强提示。TLS 让多种应用共享保护层和入口,尤其集中到 443。共享降低部署门槛,却让“连到这个端口就一定说这种语法”的推断失效。
TLS 完成以后再发起一次应用协商,可以消除歧义,但多花一轮网络往返。直接发送一种语法,再让服务器尝试识别,则会把分歧拖到应用数据之后。届时同一串受完整性保护的字节,仍可能被两端当作不同协议。
ALPN 借用了本来就要发生的握手。客户端在 ClientHello 中提供集合,服务端在握手完成前给出单一选择。第一段应用数据抵达时,连接已经拥有共同语法。
RFC 8170 把这段历史放在 HTTP/2 部署中说明:受 TLS 保护的 HTTP/2 需要避免额外往返,因此采用 ALPN;非加密变体使用 Upgrade。后来 ALPN 成为协商未来 HTTP 版本的主要方式。这里的关键不是把 HTTP 放进 TLS,而是把“端口暗示”改成“每条连接的显式决定”。
客户端排序没有夺走服务器选择权
ALPN 候选是非空、不截断的不透明字节串。客户端按自己的偏好排序。排序说明它更希望使用什么,不是向服务器下达第一项必须获胜的命令。
服务器有自己的支持集合和优先级。RFC 7301 要求它只在客户端列出的项目中选择,并建议从交集中选服务器最偏好的一项。客户端因此掌握可接受边界,服务器保留本地服务政策;谁也不能替对方增加一种语法。
回答只能是一个标识。一旦返回,该标识就对当前连接具有决定性。服务器不能宣布 h2,随后因为后端方便而发送 HTTP/1.1。ALPN 不是能力清单的回显,而是对后续解释方式的承诺。
这也说明监控为什么必须保存双方证据。只记“客户端支持 h2”,无法解释服务端为什么选了 http/1.1;只记软件版本“支持 h2”,无法证明这台实例、这个租户或这份配置当时允许选择。真正可审计的是候选顺序、服务端策略版本、实际选择与实例身份。
没有交集就不该假装兼容
如果服务端不支持客户端列出的任何项目,RFC 7301 要求返回致命的 no_application_protocol。这不是普通应用层拒绝,因为应用语法尚未确立;也不是让客户端随便选一种旧协议继续发送。
静默回退看起来提高成功率,实则抹掉两端唯一共同知道的事实:它们没有共同语法。客户端不知道服务端选择了什么,服务端可能等待客户端从未承诺的格式。TLS 只保证字节没有被篡改,并不会让两个解析器自动达成一致。
RFC 9325 后来把严格执行这一规则写进 TLS 最佳实践。原因不只是互操作性,还包括跨协议混淆:本来面向一种服务的消息若被另一种服务解析,可能产生意外操作。ALPN 不能消除所有此类攻击,但服务端若接受客户端未提出的标识,就主动丢弃了已有的一道边界。
失败因此是一种有价值的生产证据。它能暴露仍需旧协议的客户端、尚未完成的节点发布、错误的优先级或不兼容的 QUIC 版本。为了让错误率好看而隐藏它,会把可修复的不兼容变成无法定位的语义漂移。
票据能恢复计算,不能恢复语法
TLS 会话恢复与 session ticket 的目的,是在政策允许时复用一部分密码学建立成果。如果上一条连接选过 h2,最省事的想象是让票据把它一并带回来。
RFC 7301 明确否定这种继承:ALPN 是连接属性,不是会话属性;恢复时旧扩展内容无关,只有新握手里的值有效。
原因并不神秘。客户端可能已经删除一种协议。服务端可能把新协议提升到首选。票据可能落到另一台节点。负载均衡、区域或租户配置可能改变。如果旧选择绑定在票据上,性能优化就会取得锁定未来应用政策的权力。
同一张票据前后选择不同,也不自动说明恢复损坏。它可能准确显示新节点的交集与偏好。诊断必须比较两次握手各自的候选、选择、配置与路径,不能用“session resumed”概括成“整个应用会话原样继续”。
0-RTT 不能抢在新语法前面
TLS 1.3 允许符合条件的恢复连接携带 early data。客户端可在新握手完全结束之前先发应用字节。这使“旧选择不继承”成为立即影响数据处理的规则。
RFC 8446 规定:除非新连接选中了相同的 ALPN 协议,TLS 实现不得自动重发 early data。若旧连接是 HTTP/2,新连接却选了 HTTP/1.1,把原字节机械地塞进去,会在协议意义改变后重复动作。
“ALPN 相同”也只是一项必要条件。它不能证明请求可重复、凭据仍有效、前一次没有执行,或应用具备幂等性。重放判断属于应用。TLS 能确认的是更窄的事实:在协议名已变化时,自动重发连语法连续性都无法成立。
票据因此不能成为业务去重凭证。它既不承诺 exactly-once,也不授权某个 origin。它只在密码学协议定义的范围内参与新握手。
HTTP/2 在选择以后仍要发送前言
RFC 9113 规定 TLS 上的 HTTP/2 使用 h2,并必须通过 ALPN 选择。h2c 描述非 TLS 版本,不能在 TLS ALPN 中提交或选中。
TLS 完成后,双方还必须发送 HTTP/2 connection preface。客户端以特定字节序列和 SETTINGS 开始,服务端以 SETTINGS 开始。前言不是对 ALPN 的无谓重复。
ALPN 回答“哪一种语法被允许接管这条连接”;前言回答“接下来实际收到的字节是否按这种语法开始,并带有哪些初始参数”。服务端选了 h2 却收到错误前言,说明故障发生在选择之后。只看到前言却没有握手记录,也无法证明 TLS 两端曾经同意 h2。
这两层证据还能揭示错误路由:边缘 TLS 终结器可能正确选择 h2,却把流量交给只会 HTTP/1.1 的后端。把全部数据压成一个“HTTP/2 已开启”配置项,会隐藏真正跨越组件的交接失败。
QUIC 把协议选择纳入连接成立条件
RFC 9001 用 TLS 保护 QUIC,并要求密码学握手提供经过认证的应用协议协商;没有其他机制时必须使用 ALPN。若没有谈成应用协议,端点必须立即以对应错误关闭连接。
此外,某个应用协议可以限制自己适用的 QUIC 版本。服务端不能只看名称有交集,还必须确保选择与客户端采用的 QUIC 版本兼容;客户端也要拒绝不兼容组合。
这里同时出现三个本地决定:客户端能说什么,服务端愿意提供什么,本条传输连接能承载什么。标准没有设立中央调度者替双方分配协议。它提供一个共同的选择与失败语法,让自治端点在应用数据产生状态之前达成一致。
注册表只证明字节名有归属
IANA TLS 扩展与 ALPN 标识注册表 记录扩展类型 16,并以 Expert Review 管理协议标识。表中包括 http/1.1、h2、h3,也保留了明确禁止在 TLS ALPN 使用的 h2c。
注册解决的是独立实现对同一协议使用同一字节串的问题。它不证明客户端实际发送,不证明服务端实际选择,不统计流量,也不担保选择后的程序实现安全。
生产证据必须分层:注册表说明一个值被分配给什么规范;握手说明这条连接实际提交和选择了什么;应用前言与请求轨迹说明后续字节是否进入正确解析器;授权系统再说明某项操作是否允许。
ALPN 的价值正来自这种克制。它给连接一种明确语法,却不把语法选择扩张成身份、授权或永久会话属性。旧票据可以回来,旧协议决定必须留在旧连接里。
同一个证书也不能替新连接回答
票据之外,还有两个常被误当成连续性证明的条件:地址相同与证书相同。它们都很重要,却都没有覆盖 ALPN 的问题。地址说明网络路径抵达某个 endpoint;证书验证说明 peer 在客户端信任规则下给出了可接受的身份材料。两者都没有说明这一次该由哪个应用 parser 接管数据。
一套共享证书可以部署在多个节点上。节点的 ALPN 支持、优先级和后端映射可能分批更新。证书仍然有效时,应用选择却可以不同。反过来,同一 ALPN 值也不说明证书检查一定成功,更不说明 server 对某个 HTTP origin 具有回答权。
因此故障记录应避免一个“connection secure”总字段吞掉全部阶段。至少要分别保留:网络建立、证书验证、ALPN 交集、服务端选择、应用前言、origin routing 和 authorization。若一条恢复连接从 h2 变成 http/1.1,调查应先对比当前节点和政策;若证书失败,则 ALPN 选择无论是什么都不能补救身份判断;若应用返回 421,则说明协议连接已经存在,但 origin 与连接上下文仍不匹配。
把这些决定拆开不会增加中心协调者,反而允许各责任方只对自己的事实负责。TLS 团队可以轮换证书和 ticket key,应用团队可以改变 protocol preference,origin 团队可以拒绝错误连接上下文。连接成功不是一张覆盖所有边界的通行证。
来源
- RFC 7301,Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension:https://www.rfc-editor.org/rfc/rfc7301.html
- RFC 8170,Planning for Protocol Adoption and Subsequent Transitions:https://www.rfc-editor.org/rfc/rfc8170.html
- RFC 8446,The Transport Layer Security (TLS) Protocol Version 1.3:https://www.rfc-editor.org/rfc/rfc8446.html
- RFC 9001,Using TLS to Secure QUIC:https://www.rfc-editor.org/rfc/rfc9001.html
- RFC 9113,HTTP/2:https://www.rfc-editor.org/rfc/rfc9113.html
- RFC 9325,Recommendations for Secure Use of TLS and DTLS:https://www.rfc-editor.org/rfc/rfc9325.html
- IANA,Transport Layer Security Extensions and ALPN Protocol IDs:https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
这些资料提供规范、建议与注册状态,不是当前部署率、流量占比或具体产品配置的普查。
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
