FreeBSD之netgraph简要解析(3)

最后看一下netgraph的依赖关系,在netgraph中,每张图都是相对独立的,数据包从某处进入一张图A,然后从某处出来,在另一处再进入图B,此时它将不能再使用图A。这和Netfilter不同,Netfilter基于HOOK设计,使用一些match来进行filter,比如NAT就需要ip_conntrack,ctdir需要ip_conntrack等等,ip_conntrack一直都面临table full的问题,因此你要用raw表的NOTRACK这个target来免除追踪不感兴趣流量来缓解这个问题。有下面的需求:
从网段M发出到网段N的流量(两个方向)打上tag待策略路由来处理,从网段N发出到网段M的流量(两个方向)不打tag。
分析:
很显然要使用ctdir这个match,否则将会过滤掉返回流量,于是有以下target为NOTRACK的match:
!dst N/interface $内网口
然而意味着从网段N发出到达M的返回流量也将被conntrack,这是因为ctdir和conntrack相互依赖才导致了这样的问题,在raw表中,你甚至都不知道数据包到底是走INPUT还是FORWARD,所以你很难让所有这一切关联起来,虽然conntrack可以保持一个流信息在内存中,但是却可能存在大量不相关的流也被保存。如果使用netgraph呢?很简单,我们可以写在两个命令中:
No.x check-status
No.z skip No.y from N to M   #对于返回流量,只检测conntrack
No.y netgraph tag from M to N keep-status

如此即可。FreeBSD不需要conntrack,它内建了一个动态ruleset,凡是keep-status的流量都将自动将返回流量加入动态ruleset中,实际上也就是“保持了一个流信息在内存中”,FreeBSD的conntrack和单独的rule相关联而不是和整个协议栈关联,这实际上也是netgraph的思想,我们看一下rule相关的conntrack和协议栈香瓜的conntrack的区别:
IPFW:没有全局的conntrack信息,然而需要查询动态ruleset,以匹配返回流量;
Netfilter:需要查询全局的conntrack表,可以取出一切头包经过时流量的匹配结果,不需要也没有动态ruleset

我们看一下全局的conntrack和全局的ruleset所针对的对象有何不同。很简单,全局的conntrack针对除了NOTRACK的所有的数据包,然而如果NOTRACK需要指明方向,就会需要循环依赖,问题将无解。全局的动态ruleset仅仅针对匹配到的数据包,对其它的没有匹配到的数据包除了一个查询性能影响之外没有其他影响,事到如今,我想查询性能应该不是问题吧,再说动态ruleset一般都比全局conntrackset小得多,查询conntrackset都不怕,查询动态ruleset就怕了么?换句话说,Netfilter的ip_conntrack是宁可枉杀一千,不能使一人漏网,而ipfw则是精确的匹配。效率啊,BSD不愧是网络领头军!

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://127.0.0.1/wyysgg.html