一、前言

本文,接着上篇《Linux下Netfilter/IPTables防火墙案例分析》来说说七层过滤。

 

iptables等防火墙工作在四层及四层以下,都是通过数据包过滤或能够基于传输层状态检测的。

但是一般企业应用的时候,很多场景下,需要提供屏蔽不良内容、封堵某些应用层软件的功能。

 

QQ是一款最常用的即时通讯软件,但是很多情况下,它的使用会影响工作效率,所以有需求要把QQ屏蔽掉。

如果识别QQ的特征?

  • IP检查,不行。因为它的服务器IP地址段有可能变化。

  • 端口检查,不行。局域网必须放行向外的TCP 80、UDP 53等端口,局域网主机可以访问对外网的80端口的以访问正常的网页,访问53端口以进行DNS解析。

  • 状态检测,不行,由内向外发起连接建立请求,这是合法的。

  • 字符串检测,不行,误伤太多,正常出现的某些特征字符串被过滤了,而且QQ数据可能被编码了。况且侦测每一个数据包进行字符串匹配效率也不高。

那么,就需要一款七层工作的工具,能够识别这些数据包的特征,进行封堵。

 

L7-filter就是这样的一款软件。

L7-filter要工作需要结合工作在内核中Netfilter,所以需要向内核打补丁,其实说白了就是修改源码。

 

二、实验

(一)规划

规划

几点说明:

1、上图只是画出实验环境的拓扑,生产环境拓扑应该和这个有很大差别

2、网关处在网络边缘,应该加装防火墙

3、如果内网向外提供服务,网络边缘主机应该具有公网IP,否则要通过其他技术建立连接

4、如果DMZ存在,应该网络边缘网关主机还需开放相应的端口,其拓扑位置也需调整

 

(二)实验准备

官方下载2.6.35内核,点击这里

官方下载 netfilter-layer7-v2.23.tar.gz。下载 l7-protocols-2009-05-28.tar.gz

官方下载iptables源码rpm包,iptables-1.4.7-11.el6.src.rpm

 

(三)为kernel打补丁

# tar xf linux-2.6.35.9.tar.bz2 -C /usr/src/    
# tar xf netfilter-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 23 root root 4096 Nov 23  2010 linux-2.6.35.9
 
[root@localhost linux]# patch -p1 < /root/netfilter-layer7-v2.23/kernel-2.6.35-layer7-2.23.patch    
patching file include/linux/netfilter/xt_layer7.h     
patching file include/net/netfilter/nf_conntrack.h     
patching file net/netfilter/Kconfig     
patching file net/netfilter/Makefile     
patching file net/netfilter/nf_conntrack_core.c     
patching file net/netfilter/nf_conntrack_standalone.c     
patching file net/netfilter/regexp/regexp.c     
patching file net/netfilter/regexp/regexp.h     
patching file net/netfilter/regexp/regmagic.h     
patching file net/netfilter/regexp/regsub.c     
patching file net/netfilter/xt_layer7.c

 

(四)编译安装内核

需要依赖gcc和ncurses-devel包

# cp /boot/config-2.6.32-431.el6.x86_64 .config
# yum install gcc ncurses-devel -y
# make menuconfig

 

在 Networking support ---> Networking Options ---> Network Packet filtering framework (Netfilter)  下

注意两个地方:

[ IP: Netfilter Configuration ]下

保证除proc/sysctrl compatibility with old connection tracking为空外,其他都选择为M

注意IPv4 connection tracking support选择为M,连接追踪要启用。

[ Core Netfilter Configuration ]下

Layer 7 match support为M

注意:上面的Netfilter connection tracking support也应该为M

2.1

# make
# make modules_install && make install

编译过程非常耗时,可是使用make –j 4等加速编译过程,视虚拟机或者物理机的硬件性能而定。

2.2

 

(五)使用新版内核

首先修改下/boot/grub/grub.conf,让default=0。让系统重启后,从新版内核启动。

2.3 

2.4

 

(六)制作iptables升级包

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

[root@localhost ~]# useradd mockbuild    
[root@localhost ~]# rpm -ivh iptables-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%]
[root@localhost ~]# cd rpmbuild/SOURCES/     
[root@localhost SOURCES]# tar xf iptables-1.4.7.tar.bz2                 
[root@localhost SOURCES]# cd iptables-1.4.7     
[root@localhost iptables-1.4.7]# cp /root/netfilter-layer7-v2.23/iptables-1.4.3forward-for-kernel-2.6.20forward/* ./extensions/     
[root@localhost iptables-1.4.7]# cd ..     
[root@localhost SOURCES]# tar -jcf iptables-1.4.7.tar.bz2 iptables-1.4.7/*     
[root@localhost SOURCES]# mv iptables-1.4.7/ /tmp/
[root@localhost SOURCES]# cd ../SPECS/
[root@localhost SPECS]# vim iptables.spec


 

2.5

2.6

2.7

[root@localhost SPECS]# yum install rpm-build libselinux-devel -y
[root@localhost SPECS]# rpmbuild -ba iptables.spec

完成后,生成很多目录和文件。查看包信息

2.8

开始升级iptables。

[root@localhost SPECS]# cd ../RPMS/x86_64/    
[root@localhost x86_64]# rpm -Uvh iptables-1.4.7-11.5.el6.x86_64.rpm iptables-ipv6-1.4.7-11.5.el6.x86_64.rpm     
Preparing...                ########################################### [100%]
   1:iptables               ########################################### [ 50%]
   2:iptables-ipv6          ########################################### [100%]
[root@localhost x86_64]# rpm -qa | grep iptables     
iptables-1.4.7-11.5.el6.x86_64     
iptables-ipv6-1.4.7-11.5.el6.x86_64     
[root@localhost x86_64]# rpm -ql iptables | grep layer7     
/lib64/xtables/libxt_layer7.so

 

(七)安装L7-filter协议包

这些就是各种应用程序通讯的特征码

[root@localhost ~]# tar xf l7-protocols-2009-05-28.tar.gz    
[root@localhost ~]# cd l7-protocols-2009-05-28     
[root@localhost l7-protocols-2009-05-28]# make install     
mkdir -p /etc/l7-protocols     
cp -R * /etc/l7-protocols

 

(八)测试

Linux下Netfilter/IPTables防火墙案例分析》中的防火墙设置,直接导入

[root@localhost ~]# iptables-restore < /etc/sysconfig/iptables
 
[root@localhost ~]# cat /etc/sysconfig/iptables    
# Generated by iptables-save v1.4.7 on Tue Aug 26 11:30:34 2014
*nat
:PREROUTING ACCEPT [178:16945]     
:POSTROUTING ACCEPT [2:104]     
:OUTPUT ACCEPT [6:426]     
-A PREROUTING -d 172.16.23.200/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.23.80     
-A POSTROUTING -s 192.168.23.0/24 -j SNAT --to-source 172.16.23.200     
COMMIT     
# Completed on Tue Aug 26 11:30:34 2014
# Generated by iptables-save v1.4.7 on Tue Aug 26 11:30:34 2014
*filter
:INPUT DROP [173:16649]     
:FORWARD DROP [0:0]     
:OUTPUT DROP [6:426]     
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT     
-A INPUT -p icmp -j ACCEPT     
-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT     
-A FORWARD -s 192.168.23.80/32 -p tcp -m tcp --sport 80 -j ACCEPT     
-A FORWARD -d 192.168.23.80/32 -p tcp -m tcp --dport 80 -j ACCEPT     
-A FORWARD -d 192.168.23.0/24 -p udp -m udp --sport 53 -m state --state ESTABLISHED -j ACCEPT     
-A FORWARD -s 192.168.23.0/24 -p udp -m udp --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT     
-A FORWARD -d 192.168.23.0/24 -p tcp -m tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT     
-A FORWARD -s 192.168.23.0/24 -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT     
-A FORWARD -p icmp -j ACCEPT     
-A OUTPUT -m state --state ESTABLISHED -j ACCEPT     
-A OUTPUT -d 192.168.23.0/24 -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT     
COMMIT
# Completed on Tue Aug 26 11:30:34 2014

导入上面的规则后,上网不受影响,而且QQ也可以通讯。

2.10 qq

那QQ是怎么突破防线的呢?

2.11

原来它利用了TCP的80端口,而且还是个TCP的长连接,不断开。

 

(八)启用七层过滤

# modprobe xt_layer7

2.12

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

# sysctl -a | grep conntrack_acct    
net.netfilter.nf_conntrack_acct = 1

在FORWARD上增加规则   

# iptables -A FORWARD -m layer7 --l7proto qq -j REJECT

 

测试QQ登录

2.13

[ 分析 ]

从上图中可以看出,QQ大量的对外部IP的80端口处于FIN_WAIT1状态,这是因为它和这些服务器都可以三次握手成功,但是一旦发起特制的HTTP请求,就被拦截,QQ客户端收不到服务器响应,就会尝试断开连接,发出FIN请求,但是无人回应。QQ客户端还在尝试新的连接请求。例如最下面的SYN_SENT。

 

2.14

 

至此,使用2.6.35内核,使用L7-filter结合Netfilter/IPTables,实现七层控制的实验完成。

 

三、QQ协议分析

(一)特征码分析

L7-filter中的QQ的特征码

qq    
^.?.?\x02.+\x03$

多么熟悉的表达式,我来解释一下:

十六进制数2(也就是十进制的2了)出现在第一或第二或第三字节,中间任意字节,最后一个字节以3结尾。

注意这里我没有用字符,这里的字符指的就是单字节字符,用字节描述,是为了分析包方便。

 

(二)抓包验证

我们把QQ的抓包打开看一下

QQ协议分析

果然是第三字节0x02,最后一个字节0x03,所以QQ服务器的数据包被抓住了,登录不能成功,自然就用不了了。

 

(三)简单分析一下上图中QQ的登录过程

1、QQ客户端对多个服务器的TCP 80发起TCP连接请求

2、当其中一个服务器响应

3、客户端收到后,立即回应。完成三次握手

4、客户端立即向握手的服务器发起特制的HTTP请求

这一个请求,如上图所示,符合特征码,就被拦截。

5、又有一个服务器响应到达

6、客户端立即返回对这个服务器的响应。完成三次握手

7、客户端再次向新握手的服务器发起特制HTTP请求,又被特征码匹配拦截。

QQ客户端就反复尝试,直到超时,只好报告客户端无法登陆

 

如果再深入的了解L7-filter,甚至可以自己编写特征码,来扩展对其他应用层程序的控制。但前提是要抓包分析各种软件的通讯协议,而且像QQ这种软件还在变化。

 

通过两篇博文,简单的阐述了Netfilter/IPTables框架在多种案例中的应用,通过抓包分析,简单的分析了其外在表现,并没有从内部剖析、深入分析其实现,但是只有掌握其内在原理才能真正用好防火墙,否则使用这把双刃剑可能会伤着自己。