linux iptables layer7 模块 中文howto


这两天在研究iptables layer7的文档,窃以为这个模块会弥补iptables在应用层控制方面的一些短处,今天闲来无事,恰巧一位故人也提到了layer7这个东西,干脆花了大半天的时间,把howto翻译成了中文,呵呵,水平有限,意译而已,大家看了发现什么bug和我联系阿。。。

layer7 filter howto
注意:linux 2.6.9/10和layer7会发生一个严重的内存泄露问题导致系统在几分钟之内down掉,看起来这好像是内核堆栈的问题,在2.6.11登台之前,还是用2.6.0-2.6.8.1的内核和L7 0.9.1一起工作吧

目录

1、介绍

2、你需要得到什么

3、内核补丁

4、iptables补丁

5、协议定义

6、实务

1、介绍

L7是一个linux内核包分类器,和其他的分类器不同,l7不仅仅看上去是对协议的端口定义,他的表达式和应用层协议匹配,以此检验包使用的何种协议

因为l7对于处理器和内存很敏感,我们建议当您存在下列情况时才考虑使用l7

*你需要匹配一些使用未预先定义的协议端口(主要见于p2p文件共享应用)

*你相信一些有意义的通讯使用了非标准的端口(例如http协议使用1111端口)

符合以上两个问题的其中之一吗,好吧,l7项目中有三个组成部分,一个内核补丁,一个iptables补丁,一个协议定义文件,本文一下部分就来解释你如何处理他们。

2、你需要获取的:

*从kernel.org得到2.4或者2.6的内核源代码

*从netfilter.org得到iptables的源代码

*我们的Layer7 补丁包

*我们的协议定义包

3、内核补丁

针对专家的缩写版:应用我们的内核补丁,在netfilter中打开新的匹配选项。

从Layer 7 paches包中选择适当的内核补丁,并给linux内核打补丁(请阅读包里面的readme文件选择合适的文件)。或者根据你的需要设置其他内核版本。

打开EXPERIMENTAL(Device Drivers->Networking support->Networking Options->Network packet filtering),接下来打开connection tracking(Network packet filtering->IP:Netfilter Configuration->Connection tracking)。在同一屏,同样打开Connection tracking flow accounting 和IP tables support。

打开Layer 7 match support,你需要打开其他一些Netfilter选项,比较显而易见的如Ftp support。如果你还不太了解具体的选项含义,那么就打开所有的Layer 7 mach support

向平常一样编译并安装新内核(我们的代码会导致一个警告,不管它),重启,并加载合适的内核。

如何给源代码树加载补丁。

下面给出一个一般适用于任意内核源码的方法。首先把下载得到的补丁源码解压

gunzip layer7-kernel-patch-v.X.Y.Z.patch.gz

bunzip2 layer7-kernel-patch-v.X.Y.Z.patch.bz2

接下来打补丁,在源码的根目录中:

patch -p1 < layer7-kernel-patch-vX.Y.Z.patch

你也会看到别人告诉你"gzip -cd ../patch.gz | patch -p1",这也是管用的。

4、Iptables补丁

给专家的缩写版本:应用我们的iptables补丁,这样添加:"-m layer7 --17proto [http|ftp|etc...]"

使用layer7 patches包中的补丁文件给iptables代码打补丁,完成后,运行chmod +x extensions/ .layer7-test

编译iptables,"make KERNEL_DIR=/path/to/pathed/kernel"。接着用root身份运行"make install KERNEL_DIR=/path/to/pathed/kernel"(确保在运行这一步骤前已经给内核打过补丁)。

5、定义协议(模版文件)

那些文件告诉iptables 和内核如何把协议名称对应到正则表达式,例如FTP表示为"^220[/09-/x0d -~*ftp|331[/x09-/xod -~]*password"

解压"Protocol Definitions"并创建目的目录/etc/17-protocols

现在你可以使用如下命令匹配应用层数据了

iptables -t mangle -A POSTROUTING -m layer7 --17proto http -j MARK --set-mark 1

(例子中我们使用mangle表的POSTROUTING链因为这是一个任何包都会通过的链,参阅包通路图)

注:给不愿意循规蹈矩的人

你也可以把模版安装到自定义的路径中,如果你这样做,必须定义--l7dir:参数

例如:iptables [...] -m layer7 --l7dir /home/bob/patterns --l7proto http [...]

--l7dir参数必须在l7proto参数前指定!

注:给模版文件的编写者

编写您自己的模版文件相当容易,并且这对我们的项目也相当有建设性,更多的信息请参阅The Pattern Writing HOWTO

iptables会在目录 /etc/l7-protols 或者指定目录中查找模版文件,于是,他会找到/etc/l7-protocols/http.pat 和/etc/l7-protocols/protocols/http.pat,但不会找到/etc/l7-protocols/foo/bar/http.pat

6、实务

现在你可以实际的做一些包匹配的实验了,如果你正在阅读这篇文章,可能有两件事情你比较感兴趣,1,阻断某些协议 2,控制带宽使用。

首先,一个提醒,因为你在使用l7-filter,你不需要处理所有包的分类,也许大多数匹配需求可以通过其他更低要求的方法实现。若我们提供了正常工作的例如http,imap协议匹配方法,你也许只需要使用l7-filter处理p2p程序或类似应用。

阻断

不!为什么?

*l7-filter 匹配并非万无一失,他也许同时不能确定(有的到时候一个协议看起来和另一个差不了太多)也不能否定(应用程序可以做出些我们不清楚的令人费解的东西)

*用l7-filter阻断不安全,因为某些原因,被检测到的人可以轻易逃避过去。

*很多潜伏着的程序能够使用端口跳转的手段回应我们的阻断,在很多方面,这会使判断新的数据流非常困难。

作为替代简单的扔掉封包的操作,我们建议使用QoS限制他们的带宽使用,参阅下一节

如果你坚持使用l7-filter来丢弃封包,确保你已经研究过其他的方法,例如你的http代理服务器(对于蠕虫和红色代码等很有效)

还在看这一节?好吧,其实阻断非常简单,在行尾使用"-j DROP "或者"-j REJECT"

带宽限制

要控制协议的带宽占用,你可以使用Netfilter来"标记"封包然后使用QoS过滤带有标记的封包

标记封包:iptables -t mangle -A POSTROUTING -m layer7 --l7proto imap -j MARK --set-mark 3

数字3是任意输入的一个32位的整数,接下来你就可以使用"tc"命令("traffic control",一个用户态的linux QoS工具,是iproute2包的一部分)来过滤被标记的封包。

tc filter add dev eth0 protocol ip parent 1:0 prio 1 handle 3 fw flowid 1:3

你理解最后一条命令了么,可以试着读一下"the linux advanced routing and traffic control howto(Linux高级路由和通讯控制HOWTO)"文档受点启发,这样也许可以更好的理解现在你所做的一切,但是不幸的是,tc 命令非常模糊,也许你需要一个封装的很好的脚本,好吧,到

http://l7-filter.sourceforge.net/l7-netfilter-example

http://l7-filter.sourceforge.net/l7-netfil...ample-nonbridge

可以找到一些编写好的脚本。如果你的需求和我的不太相同,也许你需要简单编辑一下,但这些脚本无疑是一个更好的起点。

处理ftp,irc等等

一些协议会开启子连接来传输数据,FTP就是个例子,如果你加载了ip_conntrack_ftp内核模块,l7-filter把ftp和所有的子连接全部认为ftp,irc和irc-dcc也是同样。

如果你想要单独检查子连接,使用标准的iptables "helper"匹配,你可以使用"-m --helper ftp"来匹配ftp子连接,注意,这在2.6.8版本前有效,helper匹配会忽略"!"参数,并且不提供"any"匹配。

"未知"匹配

l7-filter把已经放弃匹配的连接标记成"未知",相比之下,未被定义且仍被检查的链结是没有分类的。你可以把"未知"当作一个普通的协议来处理。

这是很有用的,你也许想要对未分类的连接进行操作,但因为l7-filter通常必须在匹配某一连接之前检查很多封包,你必须小心,你不能说"如果不是http,而且不是dns,那么执行x操作",因为这样,x操作也会执行到http的握手操作上,这也许不是你想要看到的。你应该说:"检查http.和dns协议,如果是"为定义"分类,执行x操作",实际操作:

iptables -t mangle -A POSTROUTING -m layer7 --l7proto http

iptables -t mangle -A POSTROUTING -m layer7 --l7proto dns

iptables -t mangle -A POSTROUTING -m layer7 --l7proto unknown -j[...]

这个特征只在2.6版本有效,2.4版本,没有定义的连接永远不会拥有一个分类。

其他应该知道的:

*一些模版需要能够观察连接的两端以便进行匹配,这对于netfilter很容易,默认的,在mangle表的POSTROUTING链的策略会应用到两端,但是output链只能看到本地生成的封包,所以,output链并不是一个好的选择。

*如果想要更新协议,你需要清空iptables规则并且重新输入他们,因为模版文件只被iptables读取,不能被内核读取。

*默认的,l7-filter只价差前8个包或者2kb,这样小了一点,你可以通过修改/proc/net/layer7_numpackets文件修改这个数字,例如:echo "12" > /proc/net/layer7_numpackets ,你也可以通过使用更大的"buffer size for application layer data"参数重新编译内核来修改最大数据大小。

*也许这样很罕见,但是连接匹配不止一个模版也是可能的,模版按照你在iptables 中指定的顺序进行校验,如果匹配,则不再继续对连接进行校验,所以,更改规则的顺序可以改变校验的结果。

*有些时候,信息写入系统日志比显示在你工作的终端上更为重要,例如一些包含正则表达式未匹配或者tc报错的消息。一个有用的命令是"tail -f /var/log/messages"  

你可能感兴趣的:(linux iptables layer7 模块 中文howto)