iptables深入解析:应用层插件篇

对于常规的iptables match或者target扩展肯定不能满足我们的需要,并且默认iptables也只识别到五元组,在深入识别已经很吃力了.显然在实际的需求面前,我们不会止步于此.下面就讲讲iptables功能扩展的插件,支持Layer7.

在Linux的防火墙体系Netfilter下有一个独立的模块L7 filter 。从字面上看Netfilter是对网络数据的过滤,L7 filter是基于数据流应用层内容的过滤。不过实际上 L7 filter的本职工作不是对数据流进行过滤而是对数据流进行分类。它使用模式匹配算法把进入设备的数据包应用层内容与事先定义好的协议规则进行比对,如果匹配成功就说明这个数据包属于某种协议。

L7 filter是基于数据流工作的,建立在Netfilter connstrack功能之上。因为一个数据流或者说一个连接的所有数据都是属于同一个应用的,所以L7 filter没有必要对所以的数据包进行模式匹配,而只匹配一个流的前面几个数据包 (比如10个数据包)。当一个流的前面几个数据包包含了某种应用层协议的特征码时 (比如QQ),则这个数据流被L7 filter识别;当前面几个数据包的内容没有包含某种应用层协议的特征码时,则L7 filter放弃继续做模式匹配,这个数据流也就没有办法被识别.

准备工作,需要下载netfilter-layer7-v2.22和l7-protocols 网址: http://l7-filter.sourceforge.net/
它的工作和之前注册match流程是一样的 需要用户空间注册match 和内核的注册.

先看看用户空间:

再看看opts:

主要还是看parse函数:

由于它是支持到iptable1.4.3 和内核2.6.28的,如果现在比较新的版本需要自己对应修改部分代码.
这里需要注册的是struct xt_layer7_info :

我们拿一个实际的例子说明:
#iptables -t nat -A POSTROUTING -m layer7 –17proto qq -j DROP
parse函数的作用就是解析参数后,读取特征码pat文件信息匹配,然后赋值给xt_layer7_info
通过parse_layer7_protocol:默认pat文件放在/etc/l7-protocols ,也可以自己指定.
看qq.pat:
#…
# that.”
# So now the pattern allows any of the first three bytes to be 02. Delete
# one of the “.?” to restore to the old behaviour.
# pattern written by www.routerclub.com wsgtrsys
qq
^.?.?\x02.+\x03$
即:protocol =“qq”;pattern=“^.?.?\x02.+\x03$”
我们可以看到协议识别的信息是一串正则表达式显然不能直接用.
对于layer7它只支持ip报文,协议只支持tcp、udp和icmp:

下面看看内核部分:

内核中的工作就是调用match解析正则表达式.

1.首先获取用户传的信息:const struct xt_layer7_info * info =par->matchinfo;
2.判断是否是支持的协议类型(ip —> tcp/udp/icmp)
3.获取当前连接ct和master ct信息
4. 判断skb是否线性
5.找到应用数据的地址:

6.利用regcomp编译传递的字符串正则表达式到regexp结构体中

7.利用total_acct_packets计算是否为第一个来的报文,如果是申请app_data空间给ct里的layer7字段
8.判断skb->cb 是否为null,为空则附加data到主ct的layer7.app_data,如果有下个报文处理则追加data.(追加的条件是什么呢?) ,(当skb附加data后会设置skb->cb[0]=1)
9.利用regexec判断匹配
10.设置skb->cb[0]=1;然后返回

这里我们特别说明下第三个:
关于ct->master的问题 这里涉及expt 即期望连接的问题,稍微回顾一下,在新建一个ct的时候会查询expect hlist看看是否是某一个ct期望的连接.

还有一个之前说的只匹配前几个包的问题(算是一个隐式bug):

具体的编译和安装测试这里不再说明.当然我们会发现这个layer7并不完美,还有许多问题需要去解决.

1 1 收藏 评论

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部