RFC8999 QUIC版本通用属性



状态: 建议标准
更多信息: 数据追踪| 知识产权| 信息页
组织: 互联网工程工作组(IETF)
RFC编号: 8999
分类: 标准追踪
出版时间: 2021年5月
国际标准期刊编号: 2070-1721
作者: M. Thomson, Ed.
Mozilla

前言

本文是关于QUIC传输层协议基础属性的网络规范文档译文,尚未完成翻译,欢迎指正。

摘要

本文定义了在所有版本的QUIC传输协议间均通用的属性。

备忘状态

本文是互联网标准追踪文档。

本文产自互联网工程任务组(IETF),已接受公开审查,并由互联网互联网工程指导委员会(IESG)批准出版。更多互联网标准相关信息详见RFC 7841第2章。

关于本文当前状态、勘误及反馈方式等相关信息请移步https://www.rfc-editor.org/info/rfc8999

1. 关于QUIC的超级简单描述

QUIC是一个终端之间面向连接的协议。终端之间通过UDP协议报文交互。这些UDP报文包含QUIC数据包。QUIC终端使用QUIC数据包建立终端之间共享协议状态的连接。

2. 所有QUIC版本之间保持不变的属性

除了提供安全、多路复用的传输功能,QUIC《QUIC协议》还支持版本协商。这将使得协议能够在以后的岁月中为适应新的需求而更新,而协议的诸多特性可以随着版本的迭代而不断改变。

本文阐述QUIC的一些在新的QUIC版本开发及部署的过程中依旧保持不变的属性。所有这些不变属性都与IP版本无关。

本文的主要目标是确保后续QUIC新版本的迭代。通过陈述QUIC的这些不可更改的属性,本文试图维持QUIC终端对QUIC协议任何其他方面的改动进行协商的能力。因此,这也保证了暴露到一条QUIC连接两个终端之外的信息量最少。QUIC协议在本文明确禁止之外的任何方面,都是可以在不同版本之间修改的。

附录A包含一份非详尽的清单,列出了一些基于对QUIC版本1的了解可能做出的不正确的猜想,这些不适用于QUIC的任何版本。

3. 规范及定义

本文中的关键字“必须MUST)”、“必须不MUST NOT)”、“需要REQUIRED)”、“强烈要求SHALL)”、“强烈要求不SHALL NOT)”、“应该SHOULD)”、“不应该SHOULD NOT)”、“推荐RECOMMENDED)”、“不推荐NOT RECOMMENDED)”、“可以MAY)”,以及“可选OPTIONAL)”应理解为BCP 14 《RFC2119》《RFC8174》所描述的,当且仅当它们像本段一样以斜体加粗方式出现的时候。

本文定义了未来QUIC版本需要的属性,即使没有使用规范语言。

本文使用了《QUIC协议》的术语及标准转换。

4. 标准规范

数据包的格式使用本章定义的符号描述,这些符号与《QUIC协议》中使用的一致。

复杂的字段被命名后,由紧随命名的一个以一对花括号括起来的字段列表描述,列表中的字段以逗号分隔。

单个字段包括长度信息、带正号的定值、可选值或本字段的副本。单个字段使用下述标准规范,且所有长度都以比特为单位:

x (A): 表示xA比特长度

x (A..B): 表示x的长度可以是从AB的所有值,省略A表示最小零位,并且省略B表示没有设置上限。这种格式的值总是以字符边界结束。

x (L) = C: 表示x有一个定值C,且x的长度为LL可以用上述任何长度格式

x (L) ...: 表示x重复0次或以上次数,且每个实例长度为L

本文使用网络字节序(也就是大端)值。字段每个字节的各个比特从高位到低位排列。

图1是一个示例结构:

示例结构 {
  一个比特位字段 (1),
  有固定值的7个比特位字段 (7) = 61,
  任意长度字段 (..),
  变量长度字段 (8..24),
  重复字段 (8) ...,
}

图1:示例格式

5. QUIC数据包

QUCI终端之间交换包含一个或多个QUIC数据包的UDP报文。本章描述QUIC包的不变特性。一个版本的QUIC准许多个QUIC数据包包含于同一个UDP报文里,但是其不变的特性只要求报文里的首个数据包保持。

QUIC定义了两类数据包头:长包头与短包头。有长包头的数据包由其首个字节的首个比特位设置为1判定,而短包头数据包这个比特位设置为0。

QUIC数据包可能被完全保护,包括包头。然而,QUIC版本协商包不会被完全保护,详见第6章

除了这里描述的值之外,QUIC数据包的有效负载是由各个版本决定且任意长度的。

5.1 长包头

图2是QUIC长包头的格式。

长包头 {
  包头格式 (1) = 1,
  版本特定相关位 (7),
  版本 (32),
  目标连接ID长度 (8),
  目标连接ID (0..2040),
  源连接ID长度 (8),
  源连接ID (0..2040),
  版本特定相关数据 (..),
}

图2:QUIC长包头

QUIC长包头数据包其首字节最高比特位设置为1,其余比特位则视具体版本而定。

随后的四个字节包含一个32位版本字段,关于版本详见第5.4章

接下来的一个字节包含紧随其后的目标连接ID字段的长度,且该长度值以字节计数,并被编码为一个8位无符号整数。目标连接ID字段紧随目标连接ID长度字段,其长度在0到255字节之间。连接ID详见第5.3章

接下来的一个字节包含紧随其后的源连接ID字段的长度,且该长度值以字节计数,并被编码为一个8位无符号整数。源连接ID字段紧随源连接ID长度字段,其长度在0-255字节之间。

数据包接下来剩余字段包含与QUIC版本特定相关的内容。

5.2 短包头

图3是QUIC短包头的格式。

短包头 {
  包头格式 (1) = 0,
  版本特定相关位 (7),
  目标连接ID (..),
  版本特定相关数据 (..),
}

图3:QUIC短包头

短包头QUIC数据包的首字节的最高位设置为0。

短包头数据包紧随首字节之后是一个目标连接ID。短包头不会包含目标连接ID长度、源连接ID长度、源连接ID或版本字段。目标连接ID的长度不会编码在短包头数据包里,也不会受限于这个特性。

数据包接下来剩余字段有与版本特定相关的语义。

5.3 连接ID

连接ID是一个任意长度的不透明字段。

连接ID的主要功能是确保底层协议(UDP、IP及更底层的协议栈)发生地址变更时不会导致一个QUIC连接的数据包被传输到错误的QUIC终端上。连接ID由终端及支持的中间设备用以确保每个数据包能够被调度到相应终端的正确实体上。对于终端而言,连接ID用于标识数据包对应的QUIC连接。

连接ID由每个终端根据版本特定的方式选择,而同一个QUIC连接的数据包可能使用不同的连接ID。

5.4 版本

版本字段包含一个4字节标识符。该值可供终端用以标识一个QUIC版本。值为0x00000000的版本字段保留给版本协商使用,详见第6章,而任何其余值均可能有效。

本文描述的属性适用于所有版本的QUIC。不符合本文所述属性的协议不是QUIC协议。后续文档可以给某个特定QUIC版本或一系列QUIC版本增加其他的属性。

6. 版本协商

QUIC终端收到一个带长包头的数据包及一个其不能理解或不支持的版本时,就可能回复一个版本协商包。短包头数据包不会触发版本协商。

版本协商包设置上首个字节的高位,也就是说它是一个在第5.1章定义的长包头数据包。版本协商包可以通过其版本字段识别,因为这个字段会被设置为0x00000000

图4是一个示例结构:

版本协商包 {
  包头格式 (1) = 1,
  未使用 (7),
  版本 (32) = 0,
  目标连接ID长度 (8),
  目标连接ID (0..2040),
  源连接ID长度 (8),
  源连接ID (0..2040),
  支持版本 (32) ...,
}

图4:版本协商包

版本协商包只有首字节最重要的那个比特位有着任意定义的值。其剩余的7个比特位标记为“未使用”,在发送的时候可以被设置为任意值,且必须被接收端忽略。

版本协商包紧随源连接ID字段后面的是一个支持版本字段的列表,该列表每个字段标识终端能够支持的版本(也就是客户端支持的QUIC版本的版本号挨个列下去)。版本协商包不包含其他字段,终端必须忽略不包含支持版本字段或包含不完整版本值的包。

版本协商包不使用完全的或加密的保护。某些特定的QUIC版本可能包含准许终端鉴别支持版本列表里的值是否存在修改或损坏的协议手段。

终端必须在其目标连接ID字段包含它收到的数据包的源连接ID值。必须将收到数据包的目标连接ID字段值复制给源连接ID字段,该值是客户端随机产生的。回显两个连接ID给客户端一些保证,表明服务端收到了包,且版本协商包不是由对其不可见的攻击者生成的。

终端收到版本协商包后,可以在随后的数据包中更改QUIC版本。终端更改QUIC版本的条件将取决于其选择的版本。

QUIC协议》详细描述了支持QUIC版本1的终端如何创建及处理一个版本协商包。

7. 安全及隐私有关考虑

中间件可能能够识别特定版本的QUIC的一些特性,并假设其他版本的QUIC表现出类似特征时,其底层正在表达一致的语义。这样的特性有好几个,详见附录A。QUIC版本1已经做了一些工作消除或隐藏一些可见的特征,但是许多这样的特性仍然维持现状。后续其他QUIC版本可能改变设计从而表现出不同的特征。

QUIC版本号不会出现在所有QUIC数据包中,这意味着以一个基于版本的特征从一条流中可靠地提取信息需要中间件为每个连接ID保留状态。

本文所述版本协商包不会被完整保护,仅仅对攻击者的介入做了适度保护。如果终端试图改用不同的QUIC版本,那么它必须验证版本协商包的语义内容。

8. 参考文献

8.1. 标准参考文献

[RFC2119] RFC文档中用于指出要求级别的关键字

Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, https://www.rfc-editor.org/info/rfc2119.

[RFC8174] RFC2119中关键字大写与小写的歧义

Leiba, B., “Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”, BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, https://www.rfc-editor.org/info/rfc8174.

8.2. 非标准参考文献

[QUIC-TLS] 使用TLS加密QUIC

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.

[QUIC-TRANSPORT] QUIC:一种基于UDP的多路复用安全传输协议

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.

[RFC5116] 一种用于认证加密的接口及算法

McGrew, D., “An Interface and Algorithms for Authenticated Encryption”, RFC 5116, DOI 10.17487/RFC5116, January 2008, https://www.rfc-editor.org/info/rfc5116.

附录A:不正确的猜想

QUIC版本1《QUIC协议》有一系列特性没有被保护为外部不可见,但是一般认为可以在后续的QUIC版本中更改。

本章列出了基于QUIC版本1的了解可能做出的一些错误猜想,其中一些陈述甚至对QUIC版本1也是错误的。这个列举并不充分,目的在于做一些阐述。

对于一个QUIC版本,下述任意一条甚至所有的陈述都可能是错的

  • QUIC使用TLS《QUIC TLS》,而链路上一些TLS的信息是可见的。
  • QUIC长包头只在连接建立阶段发生更改。
  • 五元组上的每条流都会包含一个连接建立过程。
  • 一条流的前几个包使用长包头。
  • 在一段长时间的静默前的最后一个包只包含一个确认信息。
  • QUIC使用关联数据加密认证(AEAD)函数(AEAD_AES_128_GCM,详见RFC5116)保护在连接建立阶段交换的数据包。
  • QUIC数据包号是加密的,且是数据包的初始加密字节。
  • QUIC数据包号每发送一个包递增1。
  • 客户端发送的首个QUIC握手包不能小于一个特定尺寸。
  • QUIC规定客户端发送第一个包。
  • QUIC数据包首字节的第二个比特位总是设置为1的(0x40)。
  • QUIC版本协商包只会由服务端发出。
  • QUIC连接ID很少发生改变。
  • QUIC终端会在发送完一个版本协商包后改变QUIC版本。
  • QUIC长包头的版本字段在两个方向上都是一样的。
  • QUIC包版本字段有一个代表某QUIC版本的值意味着连接用的就是相应的QUIC版本。
  • 任何一对QUIC终端之间一次只有一个QUIC连接建联。

作者地址

Martin Thomson

Mozilla

Email: mt@lowentropy.net