Linux软防火墙ACL匹配的优化介绍
首先,请求不要再诬陷Netfilter!虽然它有一些固有性能损耗,但敬请不要将iptables和Netfilter等同,如果你要抓元凶,请直接说iptables,而不要说成Netfilter!
iptables真的是弱爆了!它的ipt_do_table竟然是五大元凶之一,如果规则超过了7000,那么它就是之首(其它的元凶是nf_conntrack函数,它们也是Netfilter的HOOK)。iptables低效的原因在于它的ACL规则没有经过预处理,直接使用人类配置的方式和顺序让数据包逐个匹配,就跟在Linux协议栈中路由表没有转换成转发表而直接让数据包执行最长前缀匹配一样!这不是Linux的错,也不是Netfilter的错,而是你的错。你咋就不试着使用或者修改nf-HiPAC呢?
ACL的元素匹配可以分为“与”和“或“,一般认为,与操作在同一条规则内进行,而或操作则表示不同的规则,比如下面的规则:
iptables -A FORWARD -d $ip1 -p tcp -j DROP
iptables -A FORWARD -d $ip2 -p udp -j DROP
其中,ip1和tcp以及ip2和udp就是与操作,而两条规则则是或操作,如果我们进行分组,就会得出同组要串行,不同组可并行操作的结论。
如果将两条规则进行预处理,重新颠倒分组,我们能否不按规则而按匹配元素来重新分组呢?这么做是有理由的,因为匹配元素的数量是固定的,而规则数量则是不固定的,我们必须在海量元素之间可以执行快速的查找算法而不是顺序遍历匹配的算法,因此必须不能让海量元素作为同组元素串行。在ACL匹配过程中,遍历和快速查找都是需要的(前面说过的,同组串行-只能遍历,异组并行-可执行任意算法),但是必须记住的是,不要按照规则将规则分到一个组,而要以匹配元素为分组基准。要知道,人的理解方式和计算机的处理方式是完全不同的,甚至是相反的。
大多数的防火墙产品(Cisco,华为的暂不说,XXWRT的都有类似的补丁,也许?嗯,好象是真的,虽然我没有亲见,只是猜的...)都对待人工敲进去的ACL规则链都进行了预处理,这其实也是nf-HiPAC的方式,我之前写过几篇相关的文章。而Linux的iptables并没有任何的预处理,这就是它低效的原因,但这种低效不能归结到Linux或者Netfilter身上,请明悉。