一、前言
本文,接着上篇《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
# make
# make modules_install && make install
編譯過程非常耗時,可是使用make –j 4等加速編譯過程,視虛擬機或者物理機的硬件性能而定。
(五)使用新版內核
首先修改下/boot/grub/grub.conf,讓default=0。讓系統重啓後,從新版內核啓動。
(六)製作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
[root@localhost SPECS]# yum install rpm-build libselinux-devel -y
[root@localhost SPECS]# rpmbuild -ba iptables.spec
完成後,生成很多目錄和文件。查看包信息
開始升級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也可以通訊。
那QQ是怎麼突破防線的呢?
原來它利用了TCP的80端口,而且還是個TCP的長連接,不斷開。
(八)啓用七層過濾
# modprobe xt_layer7
查看並開啓內核參數,確保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登錄
[ 分析 ]
從上圖中可以看出,QQ大量的對外部IP的80端口處於FIN_WAIT1狀態,這是因爲它和這些服務器都可以三次握手成功,但是一旦發起特製的HTTP請求,就被攔截,QQ客戶端收不到服務器響應,就會嘗試斷開連接,發出FIN請求,但是無人迴應。QQ客戶端還在嘗試新的連接請求。例如最下面的SYN_SENT。
至此,使用2.6.35內核,使用L7-filter結合Netfilter/IPTables,實現七層控制的實驗完成。
三、QQ協議分析
(一)特徵碼分析
L7-filter中的QQ的特徵碼
^.?.?\x02.+\x03$
多麼熟悉的表達式,我來解釋一下:
十六進制數2(也就是十進制的2了)出現在第一或第二或第三字節,中間任意字節,最後一個字節以3結尾。
注意這裏我沒有用字符,這裏的字符指的就是單字節字符,用字節描述,是爲了分析包方便。
(二)抓包驗證
我們把QQ的抓包打開看一下
果然是第三字節0x02,最後一個字節0x03,所以QQ服務器的數據包被抓住了,登錄不能成功,自然就用不了了。
(三)簡單分析一下上圖中QQ的登錄過程
1、QQ客戶端對多個服務器的TCP 80發起TCP連接請求
2、當其中一個服務器響應
3、客戶端收到後,立即迴應。完成三次握手
4、客戶端立即向握手的服務器發起特製的HTTP請求
這一個請求,如上圖所示,符合特徵碼,就被攔截。
5、又有一個服務器響應到達
6、客戶端立即返回對這個服務器的響應。完成三次握手
7、客戶端再次向新握手的服務器發起特製HTTP請求,又被特徵碼匹配攔截。
QQ客戶端就反覆嘗試,直到超時,只好報告客戶端無法登陸
如果再深入的瞭解L7-filter,甚至可以自己編寫特徵碼,來擴展對其他應用層程序的控制。但前提是要抓包分析各種軟件的通訊協議,而且像QQ這種軟件還在變化。
通過兩篇博文,簡單的闡述了Netfilter/IPTables框架在多種案例中的應用,通過抓包分析,簡單的分析了其外在表現,並沒有從內部剖析、深入分析其實現,但是隻有掌握其內在原理才能真正用好防火牆,否則使用這把雙刃劍可能會傷着自己。