2010.3.15
最近做一个项目,linux下基于网络行为的防火墙,得知iptables Layer7能够在应用层实现封QQ、MSN、迅雷等应用,因此打算在自己的机器上配置一下iptables L7,以借鉴如何识别应用,并对这些应用进行有效控制。配了接近五天,昨晚终于把L7配好了(也终于睡了个好觉),今天折腾了一上午也终于把QQ成功封了,其中曲折说来话长,我还是长话短说吧。
先简略介绍下我的系统环境:
双系统,win7+ubuntu
Ubuntu linux 9.04(内核2.6.28-11-generic),后将内核升级到2.6.30.5
下面,就一步一步来配L7(有点不怎么简洁,但绝对是痛苦经历之后的经验之谈,希望对大家有帮助)。
第一步,做哪些准备?
刚开始配iptalbes L7相信很多人都有个疑问,什么样的环境才能配iptables L7(以下简称L7)?而且iptables L7的HOWTO是英文的,让人看起来就费劲-_-!
L7在部分2.4内核和2.6内核中都能安装,据本人观察,不管你的linux操作系统是redhat、centos还是新秀ubuntu,只要内核是合适的都能行,具体哪些内核合适,请点这里看内核兼容性:
http://l7-filter.sourceforge.net/kernelcompat
如果不知道自己的内核版本,可以在shell下输入命令查看:
#uname -r
我的ubuntu内核版本是2.6.28-11-generic,查看了一下兼容性,貌似可以。网上有很多方法配L7的方法,都是通过先升级内核来完成,然后打补丁完成,我本来想我的内核版本已经足够了,于是尝了一下不升级内核,直接给现有内核打补丁,后来感觉一帆风顺,但是在实际配置iptables的时候却一直报"找不到相应规则"(本来是一段英文,但是我忘了怎么写的,大致意思是这样)。没办法,只有重来,只有采取升级内核的方法来完成。
首先去网上下载兼容性还不错的2.6.30.5内核,下载内核网址是(后面会细讲如何升级内核):
http://www.kernel.org/ //文件名为linux-2.6.30.5.tar.gz
除了内核的之外,还要做准备以下三样东西:
1) netfilter-layer7-v2.22.tar.gz,升级netfiler,并用来给内核打支持Layer 7的补丁,网址: http://sourceforge.net/projects/l7-filter/
2) iptables-1.4.7.tar.bz2,升级iptables,可以支持更新的系统内核,网址:http://www.netfilter.org/projects/iptables/downloads.html
3) L7-protocolse-2009-05-28.tar.gz,最新Layer7协议,其中包含了L7所需的匹配模式,网址:http://sourceforge.net/projects/l7-filter/files/
把以上下载的东西全部放在/usr/src/目录下(其实放哪没关系,不过我看网上基本都这样做,遵照行事就行了,这样也便于下面的叙述:)
东西准备好了,开始工作!
第二步,打补丁、升级内核
首先,把 linux-2.6.30.5.tar.gz和netfilter-layer7-v2.22.tar.gz解压,命令为
#tar -zvxf linux-2.6.30.5.tar.gz
#tar -zvxf netfilter-layer7-v2.22.tar.gz
其次,给新内核补丁
#cd linux-2.6.30.5
#patch -p1 < ../ netfilter-layer7-v2.22/kernel-2.6.25-2.6.28-layer7-2.22.patch
第三,补丁打上了,不过在编译安装新内核之前还要做一些配置
#cd /usr/src/linux-2.6.30.5
#make menuconfig
这会进入内核配置界面,最重要的是要将如下两个选项先上:
Networking support --->
Networking options --->
Network packet filtering framework (Netfilter) --->
Core Netfilter Configuration --->
"layer7" match support 和 Layer 7 debugging output
(注:如果以上选项一时看不到,那可能是它前面依赖的一些选项没选到,慢慢摸索下,本人在2.4内2.6的多个版本内核里都配过,路径和选项都有些差异,因此如果这个路径跟你看到的有点不一样,不要慌,慢慢找找,只要L7补丁打好了,就能找到,其他的一些配置怎么选可以去网上搜一下,在此不在详述)
最后,内核已经配置好,就可以编译安装新内核了:
#cd /usr/src/linux-2.6.30.5
#make //由于是完全编译,所以时间可能有点长,根据机器的情况长短不一,我很不幸花了一个多小时 -_-!,干点别的事先,如果你一直盯着它看,等着睡着吧
#make modules_install
#make install //以前复制内核和System.map,及修改Grub.conf的步骤,都由make install自动实现
新内核编译安装完毕!重启(按理说是应该这么做了,不过建议你先不要慌着输命令重启,看一下下面的文章再说:)
#reboot
重启之后不要默认启动,要注意在倒数4、3、2......的时候按Esc,选择以新的内核,也就是我们现在安装的2.6.30.5内核启动。很有可能你会发现找了好久的菜单,都只有以前的内核版本可以选,无奈只好选老版本的启动了,进入系统后,uname -r了一下,也发现系统内核版本没更新,不要慌,且继续看下文如何解决:
分析一下原因:上面的编译过程没有生成initrd镜像文件,同时cat /boot/grub/menu.lst看了一下,得知make install命令没有自动把新编译的内核的配置写到grub的配置文件里去,这也难怪,启动选项里面没有新内核的选项 了。因此我们来做如下工作,让启项里有我们想要的选项:
首先,手工生成initrd镜像文件:
ubuntu下生成initrd镜像文件的命令是:mkinittramfs,系统中如果还没有这个工具,可以在ubuntu新立得软件包管理器中搜索initramfs-tools安装,当然也可以在终端中输入以下命令安装:
#apt-get install kernel-package
我只用了这个命令就安装上了,网上还有人在这个命令之后用了下面这个命令,如果用了此条命令没安装上工具的话,可以试着加用一下下面这个命令
#apt-get install initramfs-tools
完成之后用命令: "mkinitramfs -o initrd.img-2.6.30.5 2.6.30.5" ,将会在当前目录下生成一个名字为 initrd.img-2.6.30.5的initrd 镜像文件。注意:最后那个参数"2.6.30.5" 是版本号,必须与/lib/modules/目录下相应的文件夹同名。
其次,手动修改menu.lst,gedit /boot/grub/menu.lst增加的内容如下:
title Ubuntu 9.04, kernel 2.6.30.5
root ()/ubuntu/disks
kernel /boot/vmlinuz-2.6.30.5 root=UUID=0E0A73C30A73A67D loop=/ubuntu/disks/root.disk ro quiet splash
initrd /boot/initrd.img-2.6.30.5
这里有两个地方需要注意:1、注意其中的 kernel 和initrd 都指向刚刚自己生成的镜像文件;2、 root的 UUID每个人都不一样,看看自己menu.lst中原来的UUID是多少,复制过来行了。
这些步骤做好了,就可以安心的重启了。等到系统提示按 ESC 键的时候,可以选择和进入GRUB的菜单。可以看到自己的内核版本已经显示出来了。选择进入之后,一切正常。使用uname -r 命令查看,可以看到当前内核已经新的内核版本了。
第三步,升级iptables
#cd /usr/src
#tar -jxvf iptables-1.4.7.tar.bz2
#cd iptables-1.4.7
#cd /usr/src/netfilter-layer7-v2.22/iptables-1.4.3forward-for-kernel-2.6.20forward
#cp libxt_layer7.* /usr/src/iptables-1.4.7/extensions/
#cd /usr/src/iptables-1.4.7
#./configure --prefix=/ --with-ksource=/usr/src/linux-2.6.30.5
#make && make install
现在可以用iptables -V命令查看一下iptables版本,可以看到已经被更新了
安装l7-protocols模式包,L7全靠这些协议模式包来完成匹配工作,所以是必不可少的:
#cd /usr/src
#tar -zvxf l7-protocols-2009-05-28.tar.gz
#cd l7-protocols-2009-05-28
#make install
最后,测试
(为了让所有的模块都能工作,在测试前,建议重启一下)
在终端输入下面这条命令:
iptables -I OUTPUT -m layer7 --l7proto qq -j DROP //用L7自带规则来封QQ协议
如果没报任何信息基本已经没问题了,然后再通过iptables -L -n -v 看看现在防火墙的配置情况,如果已经有刚才的配置,那么,基本可以说L7也安装成功了!
关于如何彻底封QQ,很多网上的资料只给了脚本出来,个人认为这样只知其然,不知其所以然,不利于学习,因此下一篇将详细给出思路和编写过程,也有助于更好理解L7。
此文参考了多位网友的文章,在此列出,真诚致谢:
http://blog.csdn.net/zccst/archive/2009/09/02/4512259.aspx
http://ms.ntcb.edu.tw/~steven/l-penguin.s/article/kernel-layer7-filter.htm
http://blog.sina.com.cn/s/blog_5335d4340100doll.html
http://www.chinaunix.net/jh/38/914350.html