有很多时候需要处理大量的IP地址,比如:做联通和电信的智能路由。在防火墙上写规则就比较麻烦,至少要写几百条规则。
IPFW提供了一个功能:TABLE
table专门为处理大量IP而设计,可以把大量的ip放进一个table,然后作为ipfw的一个参数出现,并且table用了专门的算法,使得速度飞快。
IPFW中使用方法:
ipfw add deny ip from “table(3)” to any ip from any to any via em0
这时候,table 3作为一个整体出现在ipfw规则中,所有在table 3 中的ip,都将禁止通过em0。
table使用规则:
添加:ipfw table 3 add 192.168.1.1
删除:ipfw table 3 delete 192.168.1.1
查看:ipfw table 3 list
清空:ipfw table 3 flush
需要注意的是,table里面可以放IP段,比如:192.168.1.1/24,表示192.168.1.0-192.168.1.255整个C段。
限制测试:
按照ipfw man,table最大可能有4095个,编号从0-4096。
但是每个table可以放多少个IP段呢?手册上没说,但是按常规的推断,不是16位数就是32位数,下面写一个程序测试一下:
<?php
for ( $i=1; $i<=2;$i++){
for ( $j=0; $j<=255;$j++){
for ( $k=0; $k<=255;$k++){
$cmd = '/sbin/ipfw table 3 add ';
$ip = '10.' . $i . '.' . $j . '.' . $k;
$cmd .= $ip;
exec( $cmd );
echo $cmd . "\n";
}
}
}
?>
上面程序的地址范围为:10.1.0.0-10.2.255.255,共2个B,131072个IP地址。
运行后再看结果:
# ipfw table 3 list | wc -l
131072
所以,至少可以放数十万个IP地址(段),应该是32位的(难道能把所有ipv4都放进去?),需要注意的是,table里面可以放ipv6的ip地址,我这儿没有ipv6网络,就没有测试。
性能测试:
# ipfw add 10 allow ip from "table(3)" to any
00010 allow ip from table(3) to any
# ipfw show
00010 0 0 deny ip from table(3) to any
65535 876437 995714539 allow ip from any to any
第一条是添加一个deny规则,但是没有匹配项,其目的是让ipfw遍历table中的每一个ip,也就是搜索完整个表。
然后我们删除掉10号规则,这样ipfw就不再对table进行操作了,以此来对比ipfw对table的操作效率。
我用ping来测试,直接ping最近的网关,并且测试200秒,每秒10条icmp包。
# ping -i 0.1 -c 2000 192.168.1.254
先看带10规则的结果:
--- 192.168.1.254 ping statistics ---
2000 packets transmitted, 2000 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.204/0.874/18.187/1.875 ms
不带10规则的结果:
--- 192.168.1.254 ping statistics ---
2000 packets transmitted, 2000 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.180/0.873/18.416/1.952 ms
总结:
ipfw的table比较强大,对它的操作可以通过各类语言的system()函数进行操作,每个table可以放置成千上万的ip地址,在十万级别的ip中,搜索时间基本可以忽略,性能非常不错。
有点怀疑我的测试结果,测试过另一次,ping了200次,有0.2ms的差距,但没有记录下来,不正确的地方请各位指出。
该贴由hui.chen转至本版2014-11-5 17:04:56