Netfilter/Iptables Layer7 应用层过滤策略部署

环境:内核版本:Linux version 2.6.32-431.el6.x86_64

     iptables版本:iptables v1.4.7

     gcc版本:4.6.1

 

软件准备:wget http://download.clearfoundation.com/l7-filter/netfilter-layer7-v2.23.tar.gz

     wget https://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.35.9.tar.bz2

     wget http://download.clearfoundation.com/l7-filter/l7-protocols-2009-05-28.tar.gz

     wget http://ftp.redhat.com/redhat/linux/enterprise/6Server/en/os/SRPMS/iptables-1.4.7-11.el6.src.rpm

窗体顶端

窗体底端

简介

Netfilter/Iptables 作为一个典型的包过滤防火墙体系,对于网络层,传输层的数据包过滤具有

非常优秀的性能和效率,然而,对于一些面向局域网上网用户的Linux网关服务器,有时候还需要使

用QQ,MSN等聊天,使用BT下载工具等现象进行封锁。下面将介绍如何为Netfilter/Iptables 增加应用层过滤。

 

QQ,MSN等聊天,使用BT下载工具均使用了相对固定的应用层协议。使用L7-filter项目的补丁文件

包可以为linux内核增加相应的应用层过滤功能,结合其提供的l7-protocols第7层协议定义包,能够识别不同应用层的数据特征

 

L7-filter项目站点:http://l7-filter.sourceforge.net/  下载最新的补丁包及协议包

内核站点:http://www.kernel.org   下载内核,iptables的源码包

 

将netfilter-layer7 源码包中的对应补丁文件添加到内核源码中,对内核进行重新编译,安装,安装后使用新内核启动Linux操作系统。

 

注意:L7-filter补丁包内的数据,要与内核及iptables源码版本相匹配

注意:源码目录所在分区至少保持有2.5G的剩余磁盘空间。

窗体顶端

窗体底端

编译安装内核

 

1.解压释放netfilter-layer7和内核源码包,使用patch工具合并补丁文件

  tar xflinux-2.6.35.9.tar.bz2 -C /usr/src/   

  tar xfnetfilter-layer7-v2.23.tar.gz    

  cd /usr/src    

  ln -sn linux-2.6.35.9/linux    

  ll linux* -d    

    lrwxrwxrwx  1 root root   15 Aug 26 10:55 linux ->linux-2.6.35.9/    

     drwxrwxr-x 23root root 4096 Nov 23  2010linux-2.6.35.9

 

  #cd linux

  #patch -p1

     patching fileinclude/linux/netfilter/xt_layer7.h    

     patching fileinclude/net/netfilter/nf_conntrack.h    

     patching filenet/netfilter/Kconfig    

     patching filenet/netfilter/Makefile    

     patching filenet/netfilter/nf_conntrack_core.c    

     patching filenet/netfilter/nf_conntrack_standalone.c    

     patching filenet/netfilter/regexp/regexp.c    

     patching filenet/netfilter/regexp/regexp.h    

     patching filenet/netfilter/regexp/regmagic.h    

     patching filenet/netfilter/regexp/regsub.c    

     patching filenet/netfilter/xt_layer7.c

   注意:【patch -p1 】 中“1” 是数字 1,不是小写字母 L

  

2.重新配置内核编译参数,添加state机制及layer7支持【仍在内核编译目录】

   cp /boot/config-2.6.32-431.el6.x86_64.config

   yum -y installgcc ncurses-devel

   make menuconfig

 

   在配置界面中,方向键用于定位需要配置的项目

    select      进入子配置菜单

    exit             返回上一层

    help             查看帮助信息

    空格               切换所选项目的编译类型

  三种状态:

    []         表示不需要该功能

    [M]        将功能编译成模块

    [*]        将功能直接编入内核

 

  Networkingsupport ---> Networking options ---> Network packet filtering framework(Netfilter)

  ---> CoreNetfilter Configuration --->

  Netfilter connection tracking support 

      "layer7" match support  

      "string" match support

      "time" match support

      "iprange" address range matchsupport   

      "connlimit" matchsupport" 

      "state" match support 

      "conntrack" connection matchsupport

      "mac" address match support

      "multiport" Multiple port matchsupport

 

  Networkingsupport ---> Networking options ---> Network packet filtering framework(Netfilter)

   ---> IP:Netfilter Configuration --->

  IPv4connection tracking support (required for NAT)

      Full NAT                                                                              

        MASQUERADE target support                                                             

        NETMAP target support                                                               

        REDIRECT target support  

 

  使用Exit返回 最后当提示保存时,使用Yes确认保存,修改将保存到源码目录中的.config文件中。

 

3.编译新内核,并安装新内核文件

  make

  makemodules_install && make install

 

    新内核编译安装过程将花费较长时间,数十分钟到数小时不等

    新内核文件被安装到/boot目录,模块文件将复制到/lib/modules/2.6.35.9

 

    如果编译内核,途中断过,想重新编译,那么先使用

        makemrproper    删除不必要的文件和目录,初次编译内核不需要

        makeclean       删除不必要的模块和文件

   然后重新  makemenuconfig

 

4.调整GRUB引导菜单,使系统以新内核启动,然后重启linux服务器 从新版内核启动

  vim/boot/grub/grub.conf   【修改default=0 ,1改为0】

       default=0

      timeout=5

     splashp_w_picpath=(hd0,1)/boot/grub/splash.xpm.gz

      hiddenmenu

      title CentOS(2.6.35.9)

           root(hd0,1)

 reboot

窗体顶端

窗体底端

安装iptables/l7-protocols协议包

1、制作iptables升级包

  新建mockbuild用户,将l7-protocols-2009-05-28.tar.gz解压后的用于iptables 1.4.3和内核2.6.20之后的文件复制过来。

   注意目录层次。

 

  useraddmockbuild   

  rpm -ivhiptables-1.4.7-11.el6.src.rpm    

      warning:iptables-1.4.7-11.el6.src.rpm: Header V3 RSA/SHA256 Signature, key ID fd431d51:NOKEY    

      1:iptables              ########################################### [100%]

  cd/root/rpmbuild/SOURCES/    

  tar xfiptables-1.4.7.tar.bz2                

  cdiptables-1.4.7    

  cp/root/netfilter-layer7-v2.23/iptables-1.4.3forward-for-kernel-2.6.20forward/*./extensions/    

  cd ..    

  tar -jcfiptables-1.4.7.tar.bz2 iptables-1.4.7/*    

  mviptables-1.4.7/ /tmp/

  cd ../SPECS/

  vim iptables.spec

       Version:1.4.7

       Release:11.5%{?dist}   //修改11.5表示升级

      

       CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing"

          --with-kernel=/usr/src/linux --with-kbuild=/usr/src/linux--with-ksource=/usr/src/linux 

              //最后 三项 参数改为编译 的内核 linux所在目录

       %changelog

       * Wed May 172016 Fisher 1.4.7-11.5

       - L7-filtersupport              //在 %changelog 后添加这两段,加入更新日志(日期为当天)

 

  yum installrpm-build libselinux-devel -y

  rpmbuild -baiptables.spec

 

 

2、开始升级iptables

  cd/root/rpmbuild/RPMS/x86_64/

  rpm -Uvhiptables-1.4.7-11.5.el6.x86_64.rpm iptables-ipv6-1.4.7-11.5.el6.x86_64.rpm //可加参数 --nodeps 强制安装

  cd /tmp

  tar xfl7-protocols-2009-05-28.tar.gz

  cd  l7-protocols-2009-05-28

  make install

      mkdir -p/etc/l7-protocols

      cp -R */etc/l7-protocols

 

3、检查l7-protocols协议包

  rpm -ql iptables| grep layer7

    /lib64/xtables/libxt_layer7.so

窗体顶端

窗体底端

启用七层过滤/添加规则

1、启用七层过滤

  # modprobext_layer7

  # lsmod | grepxt_layer7

     xt_layer7              12060  0

      nf_conntrack           79850  1 xt_layer7 

 

2、查看并开启内核参数,确保net.netfilter.nf_conntrack_acct等于1

  # sysctl -a |grep conntrack_acct    

     net.netfilter.nf_conntrack_acct = 1 

 

3、在Iptables上做7层防火墙过虑限制

    vim/etc/sysctl.conf

      net.ipv4.ip_forward = 1      //开启路由转发功能

    sysctl -p

    lsmod | grep -wnf_conntrack    //查看nf_conntrack模块是否加载

       nf_conntrack           79485  6

      xt_layer7,iptable_nat,nf_nat,nf_conntrack_ipv4,nf_conntrack_ipv6,xt_state                  

 

    sysctl -a |grep acct           //查看内核连接追踪功能是否开启

    kernel.acct = 42   30

        ###如果下面值为0,修改为1

   net.netfilter.nf_conntrack_acct = 1

        ###打开下面文件加入到里面执行如下命令即可生效

    vim/etc/sysctl.conf

       net.netfilter.nf_conntrack_acct = 1

   sysctl -p

        ###也可使用此项命令修改,但一重启系统便会失效

    sysctl -wnet.netfilter.nf_conntrack_acct=1

 

4、添加规则

   支持的layer7应用层协议

     匹配格式:iptables [-t 表名] -m layer7--l7proto 协议名 

   根据时间过滤

     匹配格式:-m time --timestart 起始时间--timestop 结束时间 --weekdays 每周的那些天

   时间格式以24小时制表示,如早9:30 晚18:00

    每周一至周日对应的英文缩写表示为:Mon、Tue、Wed、Thu、Fri、Sat、Sun 也可以使用数字表示周一至周日,如:1、2、3、4、5、6、7

  根据字符串过滤

     匹配格式:-m string --string “字符串”--algo {bm|kmp}

 实例:

  使用layer7显示匹配策略过滤使用QQ,MSN Edonkey等应用层协议的数据访问

    iptables -AFORWARD -m layer7 --l7proto qq -j DROP

   iptables -AFORWARD -m layer7 --l7proto msn-filetransfer -j DROP

   iptables -AFORWARD -m layer7 --l7proto msnmessenger -j DROP

   iptables -AFORWARD -m layer7 --l7proto bittorrenr -j DROP

   iptables -AFORWARD -m layer7 --l7proto xunlei -j DROP

   iptables -AFORWARD -m layer7 --l7proto edonkey -j DROP

  使用--connlimit 显示匹配进行数据并发连接控制,超过100个并发连接将拒绝

    iptables -AFORWARD -p tcp --syn -m connlimit --connlimit-above 100 -j DROP

 

  使用--time显示匹配根据时间范围设置访问策略,允许周一到周五8:00-18:00之间的数据访问

    iptables -AFORWARD -p tcp --dport 80 -m time --timestart 8:00 --timestop 18:00 --weekdaysMon,Tue,Wed,Thu,Fri -j ACCEPT

       星期一 MON  星期二 TUE  星期三 WED  星期四 THU  星期五 FRI  星期六 SAT  星期天 SUN

 

  使用string显示匹配策略过滤包含tencent,verycd,×××,×××的网络访问

    iptables -AFORWARD   -m string --string"qq" --algo bm -j DROP

    iptables -AFORWARD  -m string --string"tencent" --algo bm -j DROP

    iptables -AFORWARD  -m string --string"verycd" --algo bm -j DROP

    iptables -AFORWARD  -m string --string "×××" --algo bm -j DROP

    iptables -AFORWARD  -m string --string "×××" --algo bm -j DROP

  其中--algo参数用于指定字符串识别算法,bm 或 kmp

 

 

5、查看支持的协议簇

    ls/etc/l7-protocols/protocols/

窗体顶端

窗体底端

问题汇总

1、在make 内核过程中报【gcc: error: elf_x86_64: No such file or directory】

   解决:gcc -v ,若gcc 版本为4.6 ,则不支持 linker-style 架构

      在内核目录arch/x86/vdso/Makefile中,大约在28,29行找到

     VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -Wl,-soname=linux-vdso.so.1 \  

               -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096

              把"-m elf_x86_64" 替换为"-m64"

     然后再继续找,大约在72行左右,找到

    VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -Wl,-soname=linux-gate.so.1

     中的 "-m elf_i386" 替换为"-m32"

 

2、在make 内核过程中报【drivers/net/igbvf/igbvf.h:129:15: 错误:重复的成员‘page’】

   解决:打开文件,看129行,代码为:struct page*page;再往上看,第124行,也有struct page*page这行代码,

   这个结构定义在内部的一个结构体中。就是他的名字与129行的重复了,而4.6.*的编译器不支持这种方式的定义,

   我们修改129行的代码为struct page *pagep;保存退出

 

3、在rpmbuild -bbiptables.spec 制作rpm包报 【***ERROR: No build ID note found in /home/wuyang/rpmbuild/BUILDROOT/******

   error: Bad exitstatus from /var/tmp/rpm-tmp.BPd1OI (%install)

   解决:在iptables.spec文件中任意位置添加如下参数:

    %define__debug_install_post   \

     %{_rpmconfigdir}/find-debuginfo.sh %{?_find_debuginfo_opts}"%{_builddir}/%{?buildsubdir}"\

   %{nil}

 

 重新打包