一.组播和网桥
1.一般的IP服务都是和底层的网卡设备没有关系的,完全由路由来决定,但是组播除外,因为组播需要将一个网卡显式的加入到一个组播组当中,一边该接口可以接收组播包,因此IP层和链路层就联系了起来。2.使能桥接的系统上,由broute来判断数据包将此设备当成一个桥设备还是一个路由器设备,如果当成路由器设备,那么桥的概念对于此数据包将彻底消失,如果当成桥设备,那么即使本地接收的情况下,IP层看到的接收也是一个桥设备而不是实际接收数据包的物理网卡设备。
3.因此很容易由于第1点和第2点引发一系列的问题,比如将一个桥接口加入组播,数据包却被broute drop掉了,实际的物理网卡和桥接网卡不符,组播不被接收,因此需要在broute的规则中将组播地址放过,或者干脆在Bridge的PREROUTING这个HOOK进行过滤。但是如果你只是想在某个实际的物理接口截获数据包,那么还是使用broute规则比较好,然后特意放过组播包,因为这些被截获的包根本就不应该进入桥接系统,一旦进入了桥接系统,就会影响IP层的Netfilter判断,起码你不能再用-i了,而要改为使用physdev模块的physdev-in这个match了。
二.iptables过滤规则的效率
iptables的规则匹配是按顺序匹配的,这就会造成随着规则数量的增加,效率会下降的问题,如何解决呢?那就是将数据包进行分类,使得大多数的不可能匹配的数据包不用去一一匹配每一条规则。基本上这种想法有两套方案:1.使用单独的自定义链来分类数据包。这是手动分类数据包的做法,需要配置者对本网络的流量类型很熟悉才能定义出美妙的规则链。比如说你想开放几个不连续的地址访问80端口,使用ipset有点大材小用了,但是你也不必写下如下的规则:
iptables -A FORWARD -s ip1 -p tcp --dport 80 -j ACCEPT
iptables -A FORWARD -s ip2 -p tcp --dport 80 -j ACCEPT
iptables -A FORWARD -s ip3 -p tcp --dport 80 -j ACCEPT
iptables -A FORWARD -s ip4 -p tcp --dport 80 -j ACCEPT
如果你这么写了,那么每一个数据包都要匹配所有的规则,你要这么写:
iptables -N SB_FORWARD
iptables -A SB_FORWARD -s ip1 -j ACCEPT
iptables -A SB_FORWARD -s ip2 -j ACCEPT
iptables -A SB_FORWARD -s ip3 -j ACCEPT
iptables -A SB_FORWARD -s ip4 -j ACCEPT
iptables -A FORWARD -p tcp --dport 80 -j SB_FORWARD
如此一来,大多数数据包仅仅需要匹配一个规则即可,那就是最后的那条规则,一旦不匹配就不需要继续了。这实际上是将共同的东西抽象了出来,将线形的规则进行了分类。Netfilter提供了自定义链的机制来使用户可以将一维链表存储的规则放到多维链表中。
2.使用hipac让内核自己分类数据包。这是使用一个Netfilter新的包分类机制完成的,它自动进行包分类,使用多维的树来维护规则而不是使用一维链表,在匹配方式上不是用规则来匹配数据包,而是用基于多维树分类的数据包来匹配存于多维树的规则,在存在大量离散规则的情况下,效果显著。
本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1268996