关注了就能看到更多这么棒的文章哦~
The trouble with IPv6 extension headers
By Jonathan Corbet
January 7, 2020
尽管花费的时间比大多数人预料的都要长,不过IPv6确实正在互联网上慢慢地在替代IPv4。我们做了一个快速研究性质的测试(对访问log进行grep分析),看到对LWN.net的访问里面有16%是在使用IPv6的。很多大企业的内部网络已经开始只用IPv6了。IPv6协议在设计时,很多方面都比IPv4更有自由度,其中一个利于扩展性的功能就是"extension header"机制。最近在kernel里有人提出一个方案来把extension-header的处理流程规范化,引起了很多担忧,大家在争论这个功能应该如何使用,以及Linux在这个过程中应该扮演什么角色。
这两个版本的IP协议里面,每个packet的头部都包含一些用来提示该如何处理这个packet的信息。最少要有原地址、目标地址,以及更高级别的协议的代号。IPv4的头部信息都是明确规定好的,很难在其中增加新的信息。IPv6设计方案里,增加了一个extension header区域,就是用来便于在将来能更容易地添加新信息的。
在定义了IPv6的RFC8200里面有描述几个extension header类型。其中两个最受重视的是“Hop-by-Hop”和“Destination” header。前者是供每个处理了这个packet的系统来操作的,而后者则是仅供目标节点使用的。这些header里面可能包括一个或者多个option,每个option都按照type-length-value (TLV)的格式来排列。RFC8200仅仅定义了少数几个option用来在header里面增加padding填充,不过有可能要再增加几个。
例如,In-situ Operations, Administration, and Maintenance options加上之后,就可以搜集到网络上流过的packet里面的telemetry(遥测)信息。Path MTU mechanism则利用了Hop-by-Hop option来确认一条通路上所能处理的maximum packet size。Firewall and Service Tickets (FAST)也是Hop-by-Hop的一个option,记录packet是否有权限经过一个网络区间或者通过一个防火墙。Segment Routing option则允许packet里指定它在网络上选择的路径。诸如此类的一些选项。
Tom Herbert一直着力于开发一系列patch来修改IPv6 extension header在Linux里的处理方式。他会增加一些基础支持,允许使用kernel module方式来注册特定的Hop-by-Hop或者Destination option,这样一来创建或解析响应的TLV就会很方便了。有些特定的option可以由非特权用户来加到packet或者connection(连接)上,其他option则需要由特权用户来增加。无论是哪种,代码都试图能确保这些option的定义规整并且排序正确。
其中争议性最大的一个功能其实并不是这组patch set里的。Herbert只是把它列作一项未来功能而已。这个功能会实现在此系统上流经的packet里面插入新的extension header的功能。这种插入Header的动作是违背了RFC8200的定义的,不过其实无法组织路由器提供商和其他各种中继设备提供商在他们的产品里面实现这个功能。这样一来就会多了很多问题,例如packet的传输可能会由于某些原因fail,但是远端的发送者完全不知道这个,还有那些专有的header可能会被发送到公共网络上去,等等等等。
网络子系统维护者David Miller不太喜欢在Linux kernel里面增加这个插入header的功能:“老实说,这个功能太容易被政府等机构乱用了。也可能被Internet服务提供商用在一些损害用户意愿和公平性的方式下,从而伤害用户。其实,这个功能最有可能的用处就是在监控和限制用户的场景下。我真不觉得这个功能可以被大家赞同,而成为一个'security'功能。”
不难想象插入header这个功能会被用在什么地方。例如,可以用来标记哪些packet应该走在慢速通路上,或者标记某些包被转发到Internet服务提供商的某个秘密服务器上去。这些用法都不是Linux开发者愿意支持的功能。因此Miller的打算其实并不出人意料,他近期不会在networking子系统里面合入这些代码。
Herbert也承认Miller的担心有道理,不过他认为无论Linux是否支持这个功能,路由器厂商都会找到办法来实现。上述这些不合理的用法,其实都并不需要用到extension header功能。而如果我们在kernel里面改善了extension header的支持的话,其实可能反而会减少今后这些滥用行为:“这其实恰恰说明了Linux对网络生态多么重要,这是唯一一个会对协议具体实现方式进行仔细审查的开发平台。如果其他替代系统被大力推广从而占据了领先地位,那么很大可能我们最终只能按照他们所实现的来,只能跟随他们的实现方式去兼容它,哪怕他们把协议念成了一本歪经。在segment routing这个领域,这种情况已经确实发生了,他们在试图杀死IP fragmentation,还有其他一些协议僵化的例子,毫无根据地限制了哪些host机可以在网络上发送packet,从而降低了我们给用户提供的方案的可用性以及安全性。”
Herbert希望看到的改进这种情况的方案是通过增加一个新的attribution option,这样至少可以允许网络管理器来确定是谁插入的extension header导致了问题。只是目前来说,没有办法知道是哪个系统趁着packet流经自己的时候把有问题的header插入进去了。总体上来说,他认为只要能告诉别人该怎么正确实现一个功能就能阻止那些恶意攻击。Miller比较怀疑这种方式是否能走得通。Herbert回应说QUIC, TLS和TCP fast open等协议都是由Linux开发者来引导着采用了更好的方案实现的。
写就本文的时候,讨论就到这里了。不过还是需要解决这个问题。出于实用目的,Linux经常用作互联网上的协议实现时的参考平台以及验证平台。如果能被Linux采用,就可以慢慢在网络上扩展开来,如果被Linux拒绝了,长远来说则会让一个功能死亡。不过如果Linux拒绝了它,那么这是Linux放弃了参与新协议开发的机会,并且如果背后的力量非常强大,其实Linux也会被牵着鼻子走。我们是应该拒绝header injection这个功能,还是试图接受它然后改造之来避免最坏情况的滥用,这是networking社区里接下来需要回答的一个问题。
全文完
LWN文章遵循CC BY-SA 4.0许可协议。
欢迎分享、转载及基于现有协议再创作~
长按下面二维码关注,关注LWN深度文章以及开源社区的各种新近言论~