云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

数据库服务器_网站建设预算费用_企业0元试用

小七 141 0

断包:IP碎片有缺陷

与公用电话网不同,因特网采用分组交换设计。但这些包裹到底有多大?CC BY 2.0图像由ajmexico提供,灵感来自这是一个老问题,IPv4-rfc很清楚地回答了这个问题。我们的想法是将问题分成两个独立的问题:两端操作系统可以处理的最大数据包大小是多少?在主机之间的物理连接中,允许的最大数据报大小是多少?当一个数据包对于物理链路来说太大时,中间路由器可能会将其分割成多个较小的数据报,以使其适合。这个过程称为"前向"IP碎片,较小的数据报称为IP碎片[1]。图片由杰夫·休斯顿提供,经许可复制IPv4规范定义了最低要求。来自RFC791:每个因特网目的地必须能够接收数据报576个八位元的一部分或碎片重新组装。[...]每个互联网模块必须能够转发一个68的数据报没有进一步碎片化的八位元。[...]第一个值——允许的重组包大小——通常没有问题。IPv4将最小值定义为576字节,但流行的操作系统可以处理非常大的数据包,通常高达65KiB。第二个比较麻烦。所有物理连接都有固有的数据报大小限制,这取决于它们使用的特定介质。例如,帧中继可以发送46到4470字节之间的数据报。ATM使用固定的53字节,经典以太网可以做到64到1500字节。该规范定义了最低要求-每个物理链路必须能够传输至少68字节的数据报。请看IPv6的最小值为460字节。另一方面,在没有碎片的情况下可以传输的最大数据报大小不是由任何规范定义的,而是随链路类型而变化。这个值被称为MTU(最大传输单元)[2]。MTU定义本地物理链路上的最大数据报大小。互联网是由非同质网络创建的,在两台主机之间的路径上可能存在MTU值较短的链路。在两个远程主机之间可以传输的最大数据包大小称为路径MTU,并且对于每个连接可能都是不同的。避免碎片化有人可能会认为,构建传输非常大的数据包并依赖路由器执行IP碎片化的应用程序是很好的。这不是个好主意。1987年,肯特和莫卧尔首次讨论了这种方法的问题。以下是几个亮点:要成功地重新组合一个包,必须传递所有片段。任何碎片都不能在飞行中损坏或丢失。根本没有办法通知对方丢失的碎片!最后一个片段几乎永远不会有最佳大小。对于大型传输,这意味着相当一部分流量将由次优的短数据报组成,这是对宝贵的路由器资源的浪费。在重新组装之前,主机必须在内存中保存部分片段数据报。这为内存耗尽攻击提供了机会。随后的片段缺少更高层的标头。TCP或UDP标头只出现在第一个片段中。这使得防火墙无法根据源端口或目标端口之类的标准过滤片段数据报。Geoff Huston在以下文章中可以找到对IP碎片化问题的更详细的描述:评估IPv4和IPv6数据包碎片分段IPv6不要分段-ICMP数据包太大图片由杰夫·休斯顿提供,经许可复制IPv4协议中包含了这些问题的解决方案。发送方可以在IP报头中设置DF(不分段)标志,要求中间路由器从不执行数据包的分段。取而代之的是,具有较小MTU的链路的路由器将"向后"发送ICMP消息,并通知发送方减少此连接的MTU。TCP协议总是设置DF标志。网络堆栈仔细查找传入的"数据包太大"[3]ICMP消息,并跟踪每个连接的"路径MTU"特征[4]。这种技术被称为"路径MTU发现",虽然它也可以应用于其他基于IP的协议,但它主要用于TCP。能够传递ICMP"Packet too big"消息对于保持TCP栈的最佳工作至关重要。互联网是如何工作的在一个完美的世界里,互联网连接的设备将合作并正确地处理片段数据报和相关的ICMP包。但实际上,IP片段和ICMP包经常被过滤掉。这是因为现代互联网比36年前预想的复杂得多。今天,基本上没有人能直接接入公共互联网。客户设备通过家庭路由器连接,家庭路由器执行NAT(网络地址转换),通常执行防火墙规则。越来越多的情况下,在包路径上有一个以上的NAT安装(例如,运营商级NAT)。然后,这些数据包会到达有ISP"中间盒"的ISP基础设施。它们在流量上执行各种奇怪的事情:强制计划上限、限制连接、执行日志记录、劫持DNS请求、实施政府授权的网站禁令、强制透明缓存或可以说是以其他神奇的方式"优化"流量。中间的盒子特别被移动电信公司使用。类似地,服务器和公共互联网之间通常有多层。服务提供商有时使用选播BGP路由。也就是说:它们处理来自世界各地多个物理位置的相同IP范围。另一方面,在数据中心中,使用ECMP等成本多路径进行负载平衡越来越流行。客户机和服务器之间的每一层都可能导致路径MTU问题。请允许我用四个场景来说明这一点。1客户机->服务器DF+/ICMP在第一个场景中,客户机使用TCP将一些数据上载到服务器,以便在所有数据包上设置DF标志。如果客户端无法预测合适的MTU,中间路由器将丢弃大数据包并向客户端发送ICMP"Packet too big"通知。这些ICMP数据包可能被配置错误的客户NAT设备或ISP中间盒丢弃。根据Maikel de Boer和Jeffrey Bosma的报告,2012年大约有5%的IPv4和1%的IPv6主机阻止入站ICMP数据包。我的经验证实了这一点。ICMP消息确实经常被丢弃以获得安全优势,但这相对容易修复。一个更大的问题是某些带有奇怪中间盒的移动互联网服务提供商。它们通常完全忽略ICMP并执行非常激进的连接重写。例如,Orange Polska不仅忽略入站的"Packet too big"ICMP消息,还重写连接状态并将MSS限制为不可协商的1344字节。2客户端->服务器DF-/碎片在下一个场景中,客户机使用TCP以外的协议上载一些数据,TCP清除了DF标志。例如,这可能是一个用户使用UDP玩游戏,或者有语音呼叫。大的出站数据包可能会在路径中的某个点上碎片化。我们可以通过使用大负载大小启动ping来模拟这一点:$ping-s 2048脸谱网当有效负载大于1472字节时,此特定ping将失败。任何更大的尺寸都会变得支离破碎,无法正常交付。服务器可能会错误地处理片段有多种原因,但一个流行的问题是ECMP负载平衡的使用。由于ECMP散列,包含协议头的第一个数据报很可能被负载平衡到与其余片段不同的服务器上,从而阻止了重新组装。有关此问题的详细讨论,请参见:我们之前的ECMP报告。Google如何使用maglevl4负载平衡器解决ECMP碎片化问题。此外,服务器和路由器配置错误也是一个重要问题。根据RFC7852,30%到55%的服务器丢弃包含碎片头的IPv6数据报。三。服务器->客户端DF+/ICMP下一个场景是关于客户端通过TCP下载一些数据。当服务器无法预测正确的MTU时,它应该收到一个ICMP"Packet too big"消息。别紧张,对吧?不幸的是,它不是,再次由于ECMP路由。ICMP消息很可能会被传递到错误的服务器-ICMP数据包的5元组哈希将与有问题的连接的5元组哈希不匹配。我们以前写过这方面的文章,并开发了一个简单的用户空间守护进程来解决这个问题。它的工作原理是将入站ICMP"Packet too big"通知广播到所有ECMP服务器,希望连接有问题的服务器能够看到它。另外,由于选播路由的原因,ICMP可能被完全传送到错误的数据中心!Internet路由通常是不对称的,来自中间路由器的最佳路径可能会将ICMP数据包定向到错误的位置。缺少ICMP"数据包太大"通知可能会导致连接暂停和超时。这通常被称为PMTU黑洞。为了帮助这种悲观的情况,Linux实现了一种解决方法——MTU探测RFC4821。MTU探测尝试自动识别由于错误MTU而丢弃的数据包,并使用启发式方法对其进行优化。此功能通过sysctl控制:$echo 1>/proc/sys/net/ipv4/tcp\u mtu探测但MTU探测并非没有自身的问题。首先,它倾向于将与拥塞相关的分组丢失错误地归类为MTU问题。长时间运行的连接往往会导致MTU的减少。其次,Linux没有实现IPv6的MTU探测。4服务器->客户端数据流-/碎片最后,存在这样一种情况:服务器使用DF位清除的非TCP协议发送大数据包。在这种情况下,大数据包将在通向客户机的路径上变得支离破碎。这种情况最好用大的DNS响应来说明。以下是两个DNS请求,它们将生成大量响应,并作为多个IP片段传递到客户端:美元