netfilter/layer7匹配简介

dyccsxg 2011-01-10

本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,严禁用于任何商业用途。

msn:yfydz_no1@hotmail.com

来源:http://yfydz.cublog.cn

1. 前言
netfilter的设计主要是为在IP层和传输层上进行过滤的,只有少数匹配具备上层数据处理能力,如string等匹配,但现在网络技术的发展已经越来越不局限通过端口来识别应用,如现在的各自下载工具,除了缺省端口外,用户都是可以自定义所使用的通信端口,这样就对防火墙的过滤带来很大麻烦,如果防火墙没有上层数据识别的能力,对这类协议的过滤是无能为力的。
 
layer7匹配的出现使得netfilter具备了一定的内容检测能力,其代码可到http://l7-filter.sf.net下载,layer7可用于TCP、UDP、ICMP协议的数据内容匹配。
 
layer7匹配的源码包括两个文件l7-protocols-<date>.tar.gz和netfilter- layer7-<ver>.tar.gz,第一个文件是各种协议的匹配模式的定义,模式文件的后缀名为“pat”,分不同的子目录,解压后复制到某个目录下,缺省把这些文件放到/etc/l7-protocols/目录下;第二个文件是源码,以补丁形式提供,包括内核netfilter和用户层的iptables的补丁,解开压缩文件后。可用命令:patch -p1 < <patch_file>来打补丁,然后重新编译内核模块和iptables模块后就能使用了。
 
2. layer7匹配iptables语法
 
layer7匹配的内容包括:协议、文件类型、蠕虫和其他一些类型,如HTTP协议中的音频、视频信息等。
 
layer7匹配的命令格式为:
 
-m layer7 [--l7dir directory] --l7proto [!] name
 
第一个选项--l7dir是可选的,表示匹配模式文件的路径,缺省是/etc/l7-protocols,不用包括子目录,能自动搜索所有的子目录,如果要使用该选项,一定要放在--l7proto选项的前面;选项--l7proto表示要匹配的协议的文件名称,layer7将搜索模式文件路径下的name.pat文件,将其中的模式定义作为模式匹配条件,只能定义一个名称。
 
模式匹配文件格式都是相同的,“#”为注释行,使用正则表达式进行模式定义,定义数据分两行,第一行为模式的名称,第二行为正则表达式表示的模式内容,基本只是定义服务器端的数据格式,不定义客户端,如HTTP协议定义为:
http
# Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF (rfc 2616)
# As specified in rfc 2616 a status code is preceeded and followed by a
# space.
http/(0\.9|1\.0|1\.1) [1-5][0-9][0-9] [\x09-\x0d -~]*(connection:|content-type:|content-length:|date:)|post [\x09-\x0d -~]* http/[01]\.[019]
 
由于模式只定义服务器段,而服务器返回的数据对于netfilter来说是属于ESTABLISHED的数据,所以要使用layer7匹配,必须是针对返回的数据进行匹配,而且要在通常的状态检测允许通过(iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT)的命令前进行,否则是检测不出什么来的。
 
3. layer7的内核实现
 
layer7的内核实现是比较理解的,主要部分就是对正则表达式的解析,然后对数据包内容进行模式的匹配查找,找到后就返回匹配正确,否则失败。如果对正则表达式比较熟悉的话是很容易理解的。
 
特别注意的是layer7在连接结构struct ip_conntrack中添加了自己的数据信息:
 
#if defined(CONFIG_IP_NF_MATCH_LAYER7) || defined(CONFIG_IP_NF_MATCH_LAYER7_MODULE)
 struct {
  unsigned int numpackets; /* surely this is kept track of somewhere else, right? I can't find it... */
  char * app_proto; /* "http", "ftp", etc.  NULL if unclassifed */
  
  /* the application layer data so far.  NULL if ->numpackets > numpackets */
  char * app_data;
  unsigned int app_data_len;
 } layer7;
#endif
 
app_proto是协议名称,如果通过前面的数据已经识别出该连接类型,后续的该连接的数据包就不用再检测数据内容了;
app_data 是协议数据内容,在开始匹配时建立,主要是起数据重组的作用,如果是由于数据量不够而导致的匹配不成功,layer7会在此将数据进行备份,使用后续数据填充,知道足够长度的数据模式进行匹配或重组的数据包太多而失败,因此这表示layer7有数据重组的功能;
 
另外,layer7考虑到了主连接和子连接的区别,如果是子连接,会查找主连接自动获取主连接的协议信息。
 
4. 结论
 
layer7匹配的出现使得netfilter对数据内容的识别能力提高了一大步,具备数据重组,子连接跟踪等功能,而且用户可以通过自己定义新的模式匹配文件来扩展其匹配功能而不需要再重新编译代码,比ipp2p匹配要强很多,唯一不足是一条命令中只支持一个协议名称,不能同时定义多个协议名称。

相关推荐