RFC 9308 - QUIC 传输协议的适用性 (Applicability of the QUIC Transport Protocol)
- 状态: Informational
- 发布日期: September 2022
- Stream: IETF
- 勘误: 无勘误
摘要 (Abstract)
本文档讨论 QUIC 传输协议的适用性, 重点关注影响在 QUIC 之上开发与部署应用协议的注意事项. 目标读者是将应用协议映射到 QUIC 的设计者以及这些应用协议的实现者.
本备忘录状态 (Status of This Memo)
本文档不是 Internet Standards Track 规范; 它以资料性目的发布.
本文档是互联网工程任务组 (Internet Engineering Task Force, IETF) 的产物. 它代表 IETF 社区的共识. 它已接受公开审阅, 并已获互联网工程指导组 (Internet Engineering Steering Group, IESG) 批准发布. 并非所有经 IESG 批准的文档都是任何级别 Internet Standard 的候选; 见 RFC 7841 第 2 节.
有关本文档当前状态、任何勘误以及如何提供反馈的信息, 见 https://www.rfc-editor.org/info/rfc9308.
版权声明 (Copyright Notice)
Copyright (c) 2022 IETF Trust and the persons identified as the document authors. All rights reserved.
本文档受 BCP 78 以及 IETF Trust 关于 IETF 文档的法律条款 (https://trustee.ietf.org/license-info) 约束 (以本文档发布之日有效者为准). 请仔细审阅这些文件. 从本文档提取的代码组件必须包含 Trust Legal Provisions 第 4.e 节所述的 Revised BSD License 文本, 并按该许可证所述不提供保证.
目录 (Table of Contents)
- 引言
- 回退的必要性
- 0-RTT
- 流的使用
- 分组化与时延
- 错误处理
- 确认效率
- 端口选择与应用端点发现
- 连接迁移
- 连接终止
- 信息暴露与连接 ID
- QoS 与 DSCP
- 版本与密码握手的使用
- 支持新版本部署
- QUIC 上的不可靠数据报服务
- IANA 考虑
- 安全考虑
- 参考文献
1. 引言 (Introduction)
QUIC [QUIC] 是一种提供多项高级特性的新传输协议. 它最初为 HTTP 用例设计, 但其能力可用于更广泛的应用. QUIC 封装在 UDP 中. QUIC 版本 1 集成 TLS 1.3 [TLS13] 以加密所有载荷数据与大部分控制信息. 使用 QUIC 的 HTTP 版本称为 HTTP/3 [QUIC-HTTP].
本文档为希望使用 QUIC 协议、而不自行实现传输栈的应用开发者提供指导. 这包括在 HTTP/3 之上运行或直接在 QUIC 之上运行的应用的一般指导.
后续各节讨论 QUIC 适用性的具体注意事项, 以及应用开发者在将 QUIC 用作其应用传输时必须考虑的问题.
2. 回退的必要性 (The Necessity of Fallback)
QUIC 以 UDP 为基底. 这支持用户态实现, 并允许穿越网络中间盒 (包括 NAT), 而无需更新现有网络基础设施.
测量研究表明, 约 3% [Trammell16] 到 5% [Swett16] 的网络会阻断所有 UDP 流量, 尽管几乎没有证据表明 UDP 相对 TCP 存在其他系统性劣势 [Edeline16]. 这种阻断意味着所有运行在 QUIC 之上的应用必须要么准备好在此类网络上接受连通失败, 要么被设计为回退到其他传输协议. 对 HTTP 而言, 该回退是 TLS over TCP.
IETF 传输服务 (TAPS) 规范 [TAPS-ARCH] 描述了面向多协议的通用 API 系统. 这对 QUIC 特别相关, 因为它处理多协议之间回退的影响.
具体而言, 需要避免回退到不安全协议或更弱版本的安全协议. 一般地, 实现回退的应用需要考虑安全后果. 回退到 TCP 与 TLS 会使控制信息暴露于网络中的修改与操纵. 此外, 降级到比 QUIC 版本 1 所用 TLS 1.3 更旧的 TLS 版本可能导致显著更弱的密码保护. 例如, 协议协商 [RFC7301] 的结果仅在使用 TLS 1.3 时具有机密性保护.
这些应用必须在缺少回退协议所不具备的 QUIC 特性时仍能运行 (可能功能受损). 对回退到 TLS over TCP, 最明显的差异是 TCP 不提供流多路复用, 因此若需要流多路复用则必须在应用层实现. 此外, TCP 实现与网络路径常常不支持 TCP Fast Open (TFO) 选项 [RFC7413], 而 TFO 可在新连接的第一个控制报文中一并发送载荷数据, 类似 QUIC 中的 0-RTT 会话恢复. 注意有证据表明, 即使成功协商 TFO, 中间盒仍可能阻断 SYN 数据 (见 [PaaschNanog]). 即便 Fast Open 端到端成功, 它也通常限于单个报文的 TLS 握手与应用数据, 不同于 QUIC 0-RTT.
此外, 尽管加密 (此处为 TLS) 与 QUIC 不可分割地集成, 但 TCP 上的 TLS 协商可能被阻断. 若无法支持 TLS over TCP, 应中止连接, 应用宜向用户提示安全通信不可用.
总之, 任何回退机制都可能带来性能下降并可削弱安全; 然而, 回退不得静默违反应用对其载荷数据机密性或完整性的期望.
3. 0-RTT
QUIC 提供 0-RTT 连接建立. 尽管 TLS 1.3 over TCP 也存在类似能力, 0-RTT 对使用 QUIC 的应用既带来机会也带来挑战.
从应用视角看, 提供 0-RTT 连接建立的传输协议与不提供 0-RTT 的协议有质的不同. 关闭并重新打开连接与尝试保持连接打开之间的相对权衡不同; 见第 3.2 节.
应用需要有意选择使用 0-RTT, 因为 0-RTT 带有重放攻击风险. 使用 0-RTT 的应用协议需要一份描述可安全发送信息类型的配置文件. 对 HTTP, 该配置文件见 [HTTP-REPLAY].
3.1. 重放攻击 (Replay Attacks)
0-RTT 报文中数据的重传或恶意重放可能导致服务器侧多次收到相同数据.
客户端在 0-RTT 报文中发送的应用数据若被重放, 可能被处理多次. 应用需要清楚什么可安全地放在 0-RTT 中发送. 希望启用 0-RTT 的应用协议需要仔细分析并描述可在 0-RTT 中发送的内容; 见 [QUIC-TLS] 第 5.6 节.
在某些情况下, 将 0-RTT 中的应用数据限制为不会在服务器上造成持久副作用的数据可能足够. 发起数据检索或建立配置是可能安全的动作示例. 幂等操作——重复与单次执行净效果相同的操作——可能安全. 然而, 也可能将各自幂等的操作组合成非幂等序列.
一旦服务器接受 0-RTT 数据, 就没有办法选择性地丢弃已接收的数据. 不过, 协议可以定义拒绝在重放时可能不安全的个别动作的方法.
某些 TLS 实现与部署可能提供部分甚至完整的重放保护, 可用于管理重放风险.
3.2. 会话恢复与保活 (Session Resumption versus Keep-Alive)
由于 QUIC 封装在 UDP 中, 使用 QUIC 的应用必须处理较短的网络空闲超时. 已部署的有状态中间盒通常在发送第一个分组时为 UDP 流建立状态, 并保持比 TCP 短得多的空闲期. [RFC5382] 建议 TCP 空闲期至少 124 分钟, 但文献中几乎没有该指南被广泛实现的证据. 然而 UDP 的短网络超时有充分记录. 根据 2010 年研究 ([Hatonen10]), UDP 应用可假定任何 NAT 绑定或其他状态条目在仅三十秒不活动后即可过期. [RFC8085] 第 3.5 节进一步讨论 UDP 保活间隔: 它要求最小值 15 秒, 但推荐更大值, 或完全省略保活.
通过使用连接 ID, QUIC 被设计为在超时后对 NAT 重绑定具有鲁棒性. 然而, 这仅在一端点在其对等方使用的地址上保持可用、且由对等方在超时后发送时才有帮助.
某些 QUIC 连接可能对 NAT 重绑定不鲁棒, 因为路由基础设施 (特别是负载均衡器) 使用地址/端口四元组引导流量. 此外, 具有地址转换以外功能的中间盒仍可能影响路径. 特别是, 某些防火墙对没有对应客户端最近状态的服务器流量不予放行.
QUIC 应用可调整空闲期以管理超时风险. 空闲期与网络空闲超时不同于连接空闲超时, 后者定义为两端点 idle timeout 参数的最小值; 见 [QUIC] 第 10.1 节. 有三种选项:
- 若应用层协议仅由无或很短空闲期的交互组成, 或协议对 NAT 重绑定的抵抗足够, 则可忽略该问题.
- 确保不存在长空闲期.
- 在长空闲期后恢复会话, 并在适当时使用 0-RTT 恢复.
第一种策略最容易, 但仅适用于某些应用.
QUIC 应用中的服务器或客户端可发送 PING 帧作为保活, 以防止连接与任何路径上状态超时. 保活使用建议因应用而异, 主要取决于时延要求与消息频率. 在此情况下, 应用映射必须指明由客户端还是服务器负责保持应用存活. 虽然 [Hatonen10] 建议在公网存在 NAT 时 30 秒可能合适, 但若部署能持续在 NAT 重绑定后存活, 或处于受控环境 (例如数据中心), 则更大值更可取, 以降低网络与计算负载.
在长空闲期中比每 30 秒更频繁地发送 PING 帧, 在某些情况下可能导致过多无效流量, 并对功耗受限 (移动) 设备造成不可接受的功耗. 此外, 短于 30 秒的超时会使处理短暂网络中断更难, 例如虚拟机 (VM) 迁移或移动中的覆盖丢失. 见 [RFC8085], 尤其是第 3.5 节.
或者, 客户端 (而非服务器) 可使用会话恢复而非发送保活流量. 在此情况下, 想要在已空闲超过服务器 idle timeout (可从 idle_timeout 传输参数获知) 的连接上向服务器发送数据的客户端可简单重连. 在可能时, 该重连可使用 0-RTT 会话恢复, 降低重启连接的时延.
4. 流的使用 (Use of Streams)
4.1. 流多路复用与流多路复用 (Stream versus Flow Multiplexing)
QUIC 在单一连接上提供多个流. 应用可将不同事务映射到不同流, 以避免队头阻塞. 这与在多个连接上多路复用 (例如 HTTP/1.1 的多连接) 不同. 应用需要决定对象、请求或消息如何映射到流.
4.2. 优先级 (Prioritization)
QUIC 本身不规定统一的流优先级方案. HTTP/3 使用扩展优先级方案 [RFC9218] 等机制. 直接在 QUIC 上运行的应用若需要优先级, 必须自行定义信号与调度策略.
4.3. 有序与可靠交付 (Ordered and Reliable Delivery)
QUIC 流提供可靠、按字节偏移有序的交付. 应用不得假设跨流的全局顺序. 若需要跨消息顺序, 必须在应用层编码.
4.4. 流控制死锁 (Flow Control Deadlocks)
流控制与连接级流控制可能造成死锁, 若应用在消费数据之前阻塞在发送上, 或未及时扩大窗口. 应用设计者必须理解流控制信用如何授予, 并避免循环等待.
4.5. 流限制承诺 (Stream Limit Commitments)
传输参数与 MAX_STREAMS 帧限制可打开的流数量. 应用必须优雅处理流限制, 并避免假定可无限打开新流.
5. 分组化与时延 (Packetization and Latency)
应用数据如何分帧会影响时延与丢包恢复. 小消息可能被合并; 大消息可能跨越多个 QUIC 分组. 应用应避免不必要的串行化依赖, 并考虑 Nagle 类延迟在用户态实现中的表现可能不同于 TCP 内核栈.
6. 错误处理 (Error Handling)
QUIC 区分连接错误与流错误. 应用协议应定义哪些失败关闭流、哪些失败关闭连接, 以及错误码语义. 错误码空间由应用协议注册与管理 (例如 HTTP/3 错误码).
7. 确认效率 (Acknowledgment Efficiency)
确认频率影响开销与恢复速度. 应用通常不直接控制 ACK, 但应意识到高速率小消息可能增加 ACK 负载. 相关工作见 [QUIC-ACK-FREQUENCY].
8. 端口选择与应用端点发现 (Port Selection and Application Endpoint Discovery)
QUIC 使用 UDP 端口. 应用需要发现对等方地址与端口 (DNS, Alt-Svc [RFC7838], 配置等). 服务名与端口注册遵循 [RFC6335] 等 IANA 程序.
8.1. 源端口选择 (Source Port Selection)
客户端源端口选择影响 NAT 行为与链路性. 频繁更换源端口可能帮助隐私, 但也可能破坏路径上的状态. 应用应遵循平台与 [RFC8085] 相关指导.
9. 连接迁移 (Connection Migration)
QUIC 支持连接迁移, 使端点在网络路径变化时保持连接. 应用应理解迁移可能暴露关联性, 并与负载均衡/选路策略交互. 并非所有部署都稳健支持迁移.
10. 连接终止 (Connection Termination)
应用应明确空闲超时、优雅关闭 (例如 HTTP/3 GOAWAY 类语义) 与立即关闭之间的差异. 丢弃状态过快可能导致用户可见错误; 保持过久会消耗资源.
11. 信息暴露与连接 ID (Information Exposure and the Connection ID)
11.1. 服务器生成的连接 ID
服务器生成的连接 ID 可用于路由与负载均衡 ([QUIC-LB]). 应用部署需要与基础设施就 CID 编码达成一致.
11.2. 用连接 ID 迁移缓解时序可链接性
更改连接 ID 可降低路径观察者的可链接性, 但并非对所有关联向量都充分.
11.3. 使用服务器 Retry 进行重定向
Retry 可用于令牌验证与负载控制. 应用应理解 Retry 对时延与 0-RTT 的影响.
12. QoS 与 DSCP (Quality of Service and Diffserv Code Point)
QUIC 分组可标记 DSCP. 但加密与多路复用使基于中间盒的细粒度应用区分更困难. 见 [RFC2475], [RFC7657]. 应用不应假定端到端 DSCP 被尊重.
13. 版本与密码握手的使用 (Use of Versions and Cryptographic Handshake)
应用应规划版本协商与密码套件演进. 回退不得削弱安全属性. TLS 1.3 集成意味着多数握手配置由 QUIC 实现管理, 但 ALPN 等仍由应用选择.
14. 支持新版本部署 (Enabling Deployment of New Versions)
部署应避免对单一版本号或 Initial 盐等线镜像细节僵化. 兼容版本协商与多版本支持有助于演进 (见相关版本协商工作).
15. QUIC 上的不可靠数据报服务 (Unreliable Datagram Service over QUIC)
[RFC9221] 定义不可靠数据报扩展. 实时应用可在可靠流之外使用数据报, 但必须处理丢失、重排序与拥塞控制交互.
16. IANA 考虑 (IANA Considerations)
本文档没有 IANA 动作.
17. 安全考虑 (Security Considerations)
QUIC 与 TLS 的安全考虑适用于使用 QUIC 的应用. 应考虑 [QUIC-TLS] 中关于可链接性、重放攻击与随机性的讨论.
此外, 迁移到新地址会在客户端地址之间向服务器暴露关联, 并可能在连接 ID 无法更改或流可被关联时向路径暴露该关联. 在支持迁移时, 需要从用户隐私角度考虑.
应用开发者应注意: 当因网络阻断 UDP 而无法使用 QUIC 时, 其使用的任何回退应保证与 QUIC 相同的安全属性. 若不可能, 连接应失败, 以允许应用显式处理回退到安全性较弱的替代方案. 见第 2 节.
此外, [QUIC-HTTP] 提供特定于 HTTP 的安全考虑. 然而, 关于跨协议攻击、流量分析与填充或迁移的讨论也可能与其他使用 QUIC 的应用相关.
18. 参考文献 (References)
18.1. 规范性引用 (Normative References)
[QUIC] Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based Multiplexed and Secure Transport", RFC 9000, DOI 10.17487/RFC9000, May 2021, https://www.rfc-editor.org/info/rfc9000.
[QUIC-INVARIANTS] Thomson, M., "Version-Independent Properties of QUIC", RFC 8999, DOI 10.17487/RFC8999, May 2021, https://www.rfc-editor.org/info/rfc8999.
[QUIC-TLS] Thomson, M., Ed. and S. Turner, Ed., "Using TLS to Secure QUIC", RFC 9001, DOI 10.17487/RFC9001, May 2021, https://www.rfc-editor.org/info/rfc9001.
18.2. 资料性引用 (Informative References)
[Edeline16] Edeline, K., et al., "Using UDP for Internet Transport Evolution", 2016.
[Hatonen10] Hätönen, S., et al., "An Experimental Study of Home Gateway Characteristics", IMC 2010.
[HTTP-REPLAY] Thomson, M., Nottingham, M., and W. Tarreau, "Using Early Data in HTTP", RFC 8470, September 2018.
[QUIC-HTTP] Bishop, M., Ed., "HTTP/3", RFC 9114, June 2022.
[RFC8085] Eggert, L., Fairhurst, G., and G. Shepherd, "UDP Usage Guidelines", BCP 145, RFC 8085, March 2017.
[RFC9221] Pauly, T., Kinnear, E., and D. Schinazi, "An Unreliable Datagram Extension to QUIC", RFC 9221, March 2022.
[TLS13] Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, August 2018.
[Trammell16] Trammell, B. and M. Kühlewind, "Internet Path Transparency Measurements using RIPE Atlas", 2016.
[Swett16] Swett, I., "QUIC Deployment Experience @Google", IETF96, 2016.
[TAPS-ARCH] Pauly, T., et al., "An Architecture for Transport Services", Work in Progress.
完整引用列表见英文源 docs/rfc-9308/index.md.
致谢 (Acknowledgments)
特别感谢 Last Call 审阅者 Chris Lonvick 与 Ines Robles.
本工作部分得到欧洲委员会 Horizon 2020 资助协议 no. 688421 (MAMI) 以及瑞士国家教育、研究与创新秘书处合同 no. 15.0268 的支持. 该支持不意味着背书.
贡献者 (Contributors)
Gorry Fairhurst, Ian Swett, Igor Lubashev, Lucas Pardue, Mike Bishop, Mark Nottingham, Martin Duke, Martin Thomson, Sean Turner, Tommy Pauly 等对本文件贡献了重要文本或反馈.
作者地址 (Authors' Addresses)
Mirja Kühlewind Ericsson Email: [email protected]
Brian Trammell Google Switzerland GmbH Gustav-Gull-Platz 1 CH-8004 Zurich Switzerland Email: [email protected]