前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >新一代传输协议QUIC——HTTP/3新在哪儿?

新一代传输协议QUIC——HTTP/3新在哪儿?

作者头像
用户1324186
发布2018-12-13 10:59:47
1.7K0
发布2018-12-13 10:59:47
举报
文章被收录于专栏:媒矿工厂媒矿工厂

近期被重点研究的HTTP-over-QUIC的新协议现在已经正式改名为HTTP/3。IETF中的QUIC工作组致力于创建QUIC传输协议。QUIC是通过UDP完成的TCP替换。QUIC最初是谷歌提出并研究的一个进行一个协议,后更名为“HTTP/2-encrypted-over-UDP”协议。

QUIC (Quick UDP Internet Connections) 是一种新的默认加密Internet传输协议,它提供了许多改进,旨在加速HTTP传输流量并使其更加安全,其目标是最终取代TCP和TLS网页协定。在这篇博文中概述了QUIC的一些关键特性,以及它们如何有益于网络,以及这种全新协议的支持过程中遇到了一些问题。

实际上有两个共享相同名称的协议:“Google QUIC”(简称“gQUIC”),是Google工程师几年前设计的原始协议,经过多年的实验,现已被采用在IETF(互联网工程任务组)标准化的情景中。

“IETF QUIC”(下面简称为“QUIC”)已经非常显着地偏离了gQUIC,因此它可以被认为是一个单独的协议。从数据包的有线格式到握手协定和HTTP映射,QUIC通过许多组织和个人的开放式协作改进了原有的gQUIC设计,其共同目标是使互联网更快,更安全。

那么,QUIC提供了哪些改进呢?

内置安全性(和性能)

QUIC与现在著名的TCP的一个更根本的差别:就是前者的研究目的是为了设计一个默认安全的传输协议。QUIC通过提供安全功能(如身份验证和加密)来实现这一点,这些功能由传输协议本身的更高层协议(如TLS)来实现。

初始的QUIC握手将TCP中典型的三向握手与TLS 1.3握手相结合,后者的握手提供端点的身份验证以及密码参数的协商。对于那些熟悉TLS协议的人来说,QUIC用自己的帧格式替换TLS记录层,同时保持相同的TLS握手消息。

这不仅确保了连接总是经过身份验证和加密,而且使得初始连接建立更快:与所需的两次往返相比,典型的QUIC握手只需要在客户端和服务器之间进行一次往返。

但QUIC更进一步,加密了可能被中间盒滥用以干扰连接的其他连接元数据。例如,当使用连接迁移时,被动路径上攻击者可以使用数据包号来关联多个网络路径上的用户活动(见下文)。通过加密数据包号,QUIC可确保它们不能用于连接除连接中的端点之外的任何实体的活动。

加密也可以成为僵化的有效补救措施,这使得协议中原本内置的灵活性(例如能够协商该协议的不同版本可以避免由于错误假设而不能在实践中使用的情况。(僵化就是延迟部署TLS1.3协议这么久的原因,只有经过多次修改才能实现防止僵化的中间盒错误。)

封头堵塞

HTTP / 2提供的主要改进之一是能够将不同的HTTP请求复用到同一TCP连接上。这允许HTTP / 2应用程序同时处理请求并更好地利用它们可用的网络带宽。这是对当时现状的重大改进,如果他们想要同时处理多个HTTP / 1.1请求(例如,当浏览器需要同时获取CSS和Javascript资源以呈现网页时),则需要应用程序启动多个TCP + TLS连接)。创建新连接需要多次重复初始握手,以及经历初始拥塞窗口加速,这意味着网页的渲染速度会降低。多路复用HTTP交换避免了这一切。

然而,这有一个缺点:由于在同一TCP连接上发送多个请求/响应,因此它们都同样受到分组丢失(例如,由于网络拥塞)的影响,即使丢失的数据只涉及单个请求。这就是所谓的“封头阻塞”。

QUIC更深入一些,为复用提供了一流的支持,使得不同的HTTP流可以依次映射到不同的QUIC传输流,但是,虽然它们仍然共享相同的QUIC连接,因此不需要额外的握手并且共享拥塞状态。QUIC 流是独立传输的,因此在大多数情况下,影响一个流的丢包不会影响其他。

这可以显著地减少例如呈现完整的网页(具有CSS、Javascript、图像和其他类型的资产)所需的时间,特别是在以高分组丢失率穿越高度拥挤的网络时。

以上的设计听起来很简单,但是为了实现这些设计QUIC协议需要打破许多网络应用程序认为理所当然的一些假设,这可能使QUIC的实现和部署更加困难。

QUIC被设计为在UDP资料元的顶端交付,以简化部署并避免来自丢弃未知协议的数据包的网络设备的问题,因为大多数设备已经支持UDP。这还允许QUIC实现存在于用户空间中,从而,例如,浏览器将能够实现新的协议特性并将它们传送给它们的用户,而不必等待操作系统更新。

然而避免中断的目标也使得防止滥用和正确地将分组路由到正确的端点的工作更具挑战性。

一个实现上述功能的NAT

典型的NAT路由器可以使用传统的4元组(源IP地址和端口,以及目的地IP地址和端口)来跟踪通过它们的TCP连接,并且通过观察在网络上传输的TCP SYN、ACK和FIN分组,它们可以检测何时可以建立新的连接以及何时终止该链接。这允许它们精确地管理NAT绑定的生存期、内部IP地址和端口之间的关联以及外部关联。

对于QUIC,这种功能还不可能实现,因为现在部署在野外的NAT路由器还不理解QUIC,所以它们对QUIC通常回到默认的、不太精确的UDP流处理,然而这种处理通常涉及使用任意的,有时非常短的超时设定,这可能会影响长时间运行的连接。

当NAT重新绑定发生时(例如由于超时设定),NAT周边外部的端点将看到来自与最初建立连接时观察到的源端口不同的源端口的数据包,这使得它仅使用4元组无法跟踪连接。

这不仅仅是NAT!QUIC打算提供的特性之一称为“连接迁移”,允许QUIC端点随意将连接迁移到不同的IP地址和网络路径。例如,当已知的WiFi网络变得可用时(比如当用户进入他们最喜欢的咖啡店时),移动客户端将能够在蜂窝数据网络和WiFi之间迁移QUIC连接。

QUIC试图通过引入连接ID的概念来解决这个问题:一个由QUIC数据包携带的可变长度的任意不透明块,可用于识别连接。端点可以使用此ID来跟踪它们负责的连接,而无需检查4元组(实际上,可能有多个ID标识相同的连接,例如,为了避免在使用连接迁移时链接不同的路径,但这种行为是由终点而不是中间框控制的)

然而,这也对使用任播寻址和ECMP路由的网络运营商造成问题,其中单个目的地IP地址可能潜在地识别数百甚至数千个服务器。由于这些网络使用的边缘路由器还不知道如何处理QUIC流量,因此可能会发生UDP数据包属于相同的QUIC连接(即具有相同的连接ID)但具有不同的4元组(由于NAT重新绑定或连接迁移)可能最终被路由到不同的服务器,从而破坏了连接。

为了解决这个问题,网络运营商可能需要采用更智能的第4层负载均衡解决方案,这些解决方案可以在软件中实施,无需接触边缘路由器即可部署(参见Facebook的Katran项目:

https://github.com/facebookincubator/katran

QPACK

HTTP/2引入的另一个好处是头部压缩(或HPACK),它允许HTTP/2端点通过从HTTP请求和响应中删除冗余来减少通过网络传输的数据量。特别是,在其他技术中,HPACK使用动态表填充了从先前的HTTP请求(或响应)发送(或接收)的报头,允许端点在新请求(或响应)中引用先前遇到的报头,而不是再次传输它们。HPACK的动态表需要在编码器(发送HTTP请求或响应的一方)和解码器(接收它们的一方)之间同步,否则解码器将无法解码它接收的内容。

通过TCP上的HTTP / 2,这种同步是透明的,因为传输层(TCP)负责以与发送它们相同的顺序提供HTTP请求和响应,更新表的指令可以简单地由编码器作为部分发送请求(或响应)本身,使编码非常简单。但对于QUIC来说,这更复杂。

QUIC可以独立地在不同的流上提供多个HTTP请求(或响应),这意味着虽然就单个流而言它负责按顺序交付数据,但是跨多个流没有排序保证。例如,如果客户端通过QUIC流A发送HTTP请求A,并且通过流B发送请求B,则由于网络中的数据包重新排序或丢失,可能会发生服务器在请求A之前接收到请求B,以及请求B被编码使得它引用了来自请求A的头,服务器将无法解码它,因为它还没有看到请求A。

在gQUIC协议中,通过简单地在同一gQUIC流上序列化所有HTTP请求和响应头(但不是主体)来解决这个问题,这意味着无论如何都会按顺序传递头。这是一个非常简单的方案,允许实现重用大量现有的HTTP / 2代码,但另一方面它增加了QUIC旨在减少的行头阻塞。因此,IETF QUIC工作组设计了HTTP和QUIC(“HTTP / QUIC”)之间的新映射以及称为“QPACK”的新报头压缩方案。

在HTTP / QUIC映射和QPACK规范的最新草案中,每个HTTP请求/响应交换使用其自己的双向QUIC流,因此没有线头阻塞。此外,为了支持QPACK,每个对等体创建两个额外的单向QUIC流,一个用于向另一个对等体发送QPACK表更新,另一个用于确认另一方接收的更新。这样,QPACK编码器只有在解码器明确确认之后才能使用动态表引用。

偏转反射

在基于UDP的协议中,一个常见的问题是它们容易受到反射攻击,其中攻击者欺骗原本无辜的服务器向第三方受害者发送大量数据,欺骗目标服务器的数据包的源IP地址,使它们看起来像来自受害者。

当服务器发送的响应碰巧大于它接收的请求时,这种攻击非常有效,在这种情况下,我们谈到“放大”。

由于在握手期间传输的初始分组(SYN,SYN+ACK,...)具有相同的长度,所以TCP通常不被用于这种攻击,因此它们不提供任何放大潜力。

另一方面,QUIC的握手非常不对称:就像TLS一样,在第一次发送中,QUIC服务器通常发送自己的证书链,它可以非常大,而客户端只需要发送几个字节(嵌入到QUIC包中的TLS ClientHello消息)。因此,客户端发送的初始QUIC数据包必须填充到特定的最小长度(即使数据包的实际内容要小得多)。然而,这种缓解仍然不够,因为典型的服务器响应跨越多个分组,因此仍然可以远大于填充的客户端分组。

QUIC协议还定义了一种显式的源地址验证机制,其中服务器而不是发送其长响应,只发送一个小得多的“重试”数据包,其中包含一个唯一的加密令牌,然后客户端必须回显给它。服务器内部有一个新的初始数据包。这样,服务器就更有信心,客户端不会欺骗自己的源IP地址(因为它收到了重试数据包)并且可以完成握手。这种缓解的缺点是它将初始握手持续时间从单次往返增加到两次。

另一种解决方案涉及减少服务器对反射攻击变得不太有效的点的响应,例如通过使用ECDSA证书(通常比其RSA对应物小得多)。工作组还一直在尝试使用现成的压缩算法(如zlib和brotli)压缩TLS证书的机制,这是gQUIC最初引入的功能,但目前在TLS中不可用。

UDP性能

QUIC经常出现的问题之一是部署在野外的现有硬件和软件无法理解它。我们已经研究了QUIC如何尝试解决网络中间箱问题,如路由器,但是另一个潜在的问题领域是通过UDP在QUIC端点本身上发送和接收数据的性能。多年来,人们尽可能多地优化TCP实现,包括在软件(如操作系统)和硬件(如网络接口)中构建卸载功能,但目前这些功能都不适用于UDP。

然而,QUIC实现也可以利用这些功能只是时间问题。以最近在LInux上实现UDP通用分段卸载的努力为例,这将允许应用程序以单个成本(或足够接近)为代价在用户空间和内核空间网络堆栈之间捆绑和传输多个UDP段。 ),以及在Linux上添加zerocopy套接字支持的那个,这将允许应用程序避免将用户空间内存复制到内核空间的成本。

总结

与HTTP / 2和TLS 1.3一样,QUIC将提供许多旨在提高网站性能和安全性以及其他基于Internet的属性的新功能。IETF工作组目前将在今年年底前提供QUIC规范的第一版,Cloudflare工程师已经在努力为所有客户提供QUIC的优势。

参考资料

[1] https://blog.cloudflare.com/the-road-to-quic/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-11-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 媒矿工厂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
多因子身份认证
多因子身份认证(Multi-factor Authentication Service,MFAS)的目的是建立一个多层次的防御体系,通过结合两种或三种认证因子(基于记忆的/基于持有物的/基于生物特征的认证因子)验证访问者的身份,使系统或资源更加安全。攻击者即使破解单一因子(如口令、人脸),应用的安全依然可以得到保障。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档