问题现象:使用ip6tables 添加端口过滤规则,只允许指定端口IPv6报文进来,测试结果显示如果是分片报文,只有第一个分片报文能够收到,后续分片会被丢弃。
内核版本:3.4.39
问题原因: 因为同样的规则如果是IPv4分片报文则能够生效,通过分析内核源码,发现问题出在netfilter IPv6连接跟踪模块。
netfilter IPv4 连接跟踪模块会对分片报文进行重组处理使得系统网络协议栈处理的是重组报文,因为iptables添加的规则优先级在连接跟踪后面,所以IPv4 的端口过滤能够生效,因为处理的是重组报文。IPv6的连接跟踪功能同样会出重组分片报文,不过重组后的报文只有netfilter 连接跟踪自己可见,网络协议栈处理的仍然是分片报文,这就使得ip6tables 规则处理的是分片报文。
解决方法:在Linux内核官网上查找更高的版本发现,在3.12.4版本上有一个补丁,这个补丁的作用就是使得IPv6 连接跟踪模块重组报文后直接传递给网络协议栈使用,这样ip6tables就能够基于端口过滤分片报文了。
注意事项:该补丁修改了skbuff.h和skbuff.c文件,为了和现有内核版本兼容,不能够直接拿来使用,只需要将连接跟踪模块相关的处理去掉就ok了。
author Jiri Pirko <jiri@resnulli.us> 2013-11-06 17:52:20 +0100 committer David S. Miller <davem@davemloft.net> 2013-11-11 00:19:35 -0500 commit 6aafeef03b9d9ecf255f3a80ed85ee070260e1ae (patch) tree 48c7f8ff1709c9874342c02c7039d4431a00b333 parent 9037c3579a277f3a23ba476664629fda8c35f7c4 (diff) download linux-6aafeef03b9d9ecf255f3a80ed85ee070260e1ae.tar.gz netfilter: push reasm skb through instead of original frag skbs