如何用IPtables限制網絡流量
如何用IPtables限制BT、電驢等網絡流量
今年4月,看到一則報道說盡管某寬帶公司現有技術可以容納的網絡用戶容量為400至600萬用戶,可是目前,在容納了45萬用戶的情況下,網絡已經擁擠不堪,時常出現斷網情況,一到上網高峰,網速就會急劇下降。
為何網絡會如此擁擠不堪?這是因為自從出現諸如電驢、Kazaa、BT等P2P軟件之后,海量的數據文件(如大容量文件交換、視頻文件下載等)逐漸占據了大部分的網絡帶寬。P2P這一新應用給用戶帶來了前所未有的方便和豐富的資源,但同時也引發了網絡帶寬和安全問題。
如何在發揮P2P強大功能的情況下對其進行一些必要的限制呢?本文將介紹在Linux中如何利用netfilter/iptables實現對P2P應用流量的限制。
升級內核
由于在公開發布的Linux內核文件中,有關iptables的各種參數里沒有關于P2P屬性的參數,所以必須通過升級Linux內核和iptables來打上這個補丁,使其支持P2P屬性設置。
在具體操作之前,先要了解一下升級內核補丁需要的一些相關軟件:linux-2.4.20-8.tar.gz、patch-o-matic-20040609.tar.bz2、iptables-1.2.8.tar.bz2、iptables-p2p-0.3.0a.tar.gz和ipp2p-0.5c.tar.gz。
這里的測試環境為Red Hat 9.0,內核為2.4.20-8。由于2.4.*是一個穩定的內核,因此不能把當前開發的一些新功能提交到主內核中去,而只能首先在patch-o-matic中測試,然后打補丁到內核中。在CVS中可以找到最新的patch-o-matic包—Patch-o-matic-20040609.tar.bz2。
有了內核支持后,還需要iptables支持,其中iptables-p2p-0.3.0a.tar.gz為netfilter/iptables組織開發的專門支持P2P的iptables擴展軟件包;ipp2p-0.5c.tar.gz為Eicke Friedrich開發的一個支持P2P的iptables擴展包。這兩個擴展包各有特色,后面將會分別介紹。
裝載模塊
首先在/usr/src下解壓軟件包:
- #bzip2 -d patch-o-matic-20040609.tar.bz2
生成patch-o-matic-20040609.tar.out。
- #tar xvf patch-o-matic-20040609.tar.out
生成補丁目錄patch-o-matic-20040609。Red Hat 9.0中默認的內核目錄為/usr/src/linux-2.4。進入補丁目錄/usr/src/patch-o-matic-20040609,由于支持P2P協議控制選項需要CONNMARK模塊,該模塊在extra子目錄下,因此需要運行如下命令來升級內核補丁。
- #KERNEL_DIR=/usr/src/linux-2.4 ./runme extra
運行該命令后會出現一個模塊選擇界面,界面有兩個區域,一個給出相關的模塊名、模塊功能、用法和語法實例;另一個給出各種選項,如N/y/b/r.../q/?,其中第一個為大寫字母,表示缺省選項,n表示下一個模塊,y表示確定,b表示上一個模塊,q表示退出。
首先應該確定當前的模塊是否需要,不需要就按“N”鍵后回車,繼續顯示下一個模塊的相關信息。當出現需要的模塊時,按“Y”鍵確認,同時應該將里面的相關語法實例抄錄下來以備用。選擇完所有需要的模塊后,按“Q”鍵退出。
#p#
編譯內核
進入內核文件所在目錄/usr/src/linux-2.4,開始編譯內核:
- #make mrproper
- #make xconfig(或#make menuconfig)
注意,在配置選項中必須選擇Networking options→IP:Netfilter Configuration→Connection mark tracking support和CONNMARK target support兩個選項。確保關鍵文件在正確位置:
- #make dep
編譯大內核:
- #make bzImage
編譯選擇的模塊:
- #make modules
將編譯后的模塊轉移到系統標準位置:
- #make modules_install
讓系統自動修改啟動配置文件grub.conf:
- #make install
重新啟動系統,選擇Red Hat Linux(2.4.20-8custom)選項,則啟動了新編譯的內核。
升級iptables
安裝iptables-1.2.8
首先解壓iptables-1.2.8.tar.bz2文件:
- #bzip2 -d iptables-1.2.8.tar.bz2
- #tar xvf iptables-1.2.8.tar.out
編譯iptables-1.2.8:
- #make KERNEL_DIR=/usr/src/linux-2.4
- #make install KERNEL_DIR=/usr/src/linux-2.4
- #make install-devel
拷貝可執行文件到相應目錄:
- #cp iptables iptables-save iptables-restore /sbin
安裝iptables-p2p軟件
首先解壓iptables-p2p-0.3.0a.tar.gz:
- #tar zxvf iptables-p2p-0.3.0a.tar.gz
- #cd iptables-p2p-0.3.0a
拷貝iptables-1.2.8的頭文件到適當的目錄:
- #cp -a /usr/src/iptables-1.2.8/include/* /usr/include
運行“make”編譯iptables-p2p,并拷貝相關文件到相應的目錄:
- #make
- #cp kernel/ipt_p2p.o /lib/modules/2.4.20-8custom/kernel/net/ipv4/netfilter/
- #cp iptables/libipt_p2p.so /lib/iptables/
安裝ipp2p軟件
首先修改Makefile文件中的源目錄、內核目錄和netfilter版本號,將以下內容:
- IKERNEL = -I/usr/src/linux/include
- IUSER = -I/usr/src/iptables-1.2.7a/include
- NETFILTER_VERSION = \"1.2.7a\"
改為:
- IKERNEL = -I/usr/src/linux-2.4/include
- IUSER = -I/usr/src/iptables-1.2.8/include
- NETFILTER_VERSION = \"1.2.8\"
編譯軟件,并拷貝庫文件到相應的目錄:
- #make
- #cp libipt_ipp2p.so /lib/iptables
裝入模塊:
- #insmod ipt_ipp2p
#p#
應用和檢測P2P限制功能
iptables-p2p的應用
1.iptables-p2p目前支持如下協議:
◆ FastTrack(KaZaa、Grokster......)
◆ eDonkey(eDonkey、eMule......)
◆ Direct Connect
◆ Gnutella(regular clients and Shareaza's gnutella 2)
◆ BitTorrent
◆ OpenFT(giFT)
需要安裝CONNMARK模塊,通過CONNMARK模塊的標記包來使用iptables-p2p。
2.通過-help參數獲取幫助:
#iptables -m p2p -help
……
P2P match v0.3.0a options:
--p2p-protocol [!] protocol[,...]
--p2p ...
match application-layer protocol(匹配的應用層協議)
Valid p2p protocols:(P2P支持的有效協議如下:)
fasttrack
gnutella
edonkey
dc
bittorrent
openft
iptables-p2p模塊通過-m p2p參數來實現對所有已知P2P連接請求的識別。注意,-m p2p只能識別P2P類型的連接請求,不能識別所有的P2P包,可以通過--p2p-protocol子參數來識別P2P的各種已知協議類型。
3.應用實例
#iptables -A FORWARD -m p2p -j DROP
阻塞網絡上所有的P2P連接請求。
#iptables -A FORWARD -m p2p --p2p-protocol fasttrack,bittorrent -j DROP
阻塞網絡上fasttrack和bittorrent協議連接請求。
在實際使用過程中必須和CONNMARK目標結合起來,然后通過tc過濾才能真正對所有P2P包進行限制。更多的信息可以參考example/limit-p2p.sh的實例腳本。
#p#
ipp2p的應用
1.ipp2p目前支持如下Linux內核和iptables版本:
◆ Linux-Kernels 2.6:2.6.3
◆ Linux-Kernels 2.4:2.4.18、2.4.19、2.4.20、2.4.21、2.4.22、2.4.23
◆ iptables(www.netfilter.org)1.2.7a、1.2.8、1.2.9
2.獲取ipp2p幫助
# iptables -m ipp2p --help
……
IPP2P v0.5c options:
--ipp2p Grab all known p2p packets
(抓所有已知的P2P包)
--ipp2p-data Grab all known p2p data packets
(抓所有已知P2P數據包)
--edk Grab all known eDonkey/eMule/Overnet packets
(抓所有已知的eDonkey/eMule/Overnet類型的包)
--edk-data Grab all eDonkey/eMule/Overnet data packets
(抓所有已知的eDonkey/eMule/Overnet數據包)
--dc Grab all known Direct Connect packets
(抓所有已知的直接連接包)
--dc-data Grab all Direct Connect data packets
(抓所有已知的直接連接數據包)
--kazaa Grab all KaZaA packets
(抓所有KaZaA包)
--kazaa-data Grab all KaZaA data packets
(抓所有KaZaA數據包)
--gnu Grab all Gnutella packets
(抓所有Gnutella包)
--gnu-data Grab all Gnutella data packets
(抓所有Gnutella數據包)
--bit Grab all BitTorrent packets (beta - handle with care)
(抓所有BitTorrent包)
--apple Grab all AppleJuice packets (beta - handle with care)
(抓所有AppleJuice包)
--soul SoulSeek (beta - handle with care)
(SoulSeek類型的包)
……
3.應用實例
ipp2p只能識別P2P連接請求,而不能識別所有P2P包,因此也必須和CONNMARK目標結合在一起使用,目前只支持TCP協議標示。下面來看一個實例。
#iptables -A PREROUTING -t mangle -p tcp -j CONNMARK --restore-mark
上面代碼表明從CONNMARK目標中恢復標記。
#iptables -A PREROUTING -t mangle -p tcp -m mark ! --mark 0 -j ACCEPT
上面代碼表明接收所有非0的標記包。
#iptables -A PREROUTING -t mangle -p tcp -m ipp2p --ipp2p -j MARK --set-mark 1
上面代碼表明將ipp2p連接標記為“1”。
#iptables -A PREROUTING -t mangle -p tcp -m mark --mark 1 -j CONNMARK --save-mark
上面代碼表明保存所有標記為“1”的包到CONNMARK目標中。
通過上面設置得到的結果是,每一個標示為P2P連接的包被標記成“1”,然后再通過tc過濾,執行下面的操作:
#tc filter add dev eth0 parent 1:0 protocol ip prio 4 handle 1 fw classid 1:11
#tc filter add dev eth1 parent 2:0 protocol ip prio 4 handle 1 fw classid 2:11
使用HTB和過濾,將所有標記為“1”的包放到每一個設備類中,通過對這些設備類的限制來達到對P2P連接帶寬的限制。
應用效果
筆者在單位防火墻上應用了iptables-p2p和ipp2p配置,對P2P的FastTrack協議進行限制后,用貪婪BT(ABC)進行測試,取得了理想的效果,能有效地限制P2P通信。
【編輯推薦】