iptables的原理及進行包過濾的用法

iptables 只是一個管理內核包過慮的工具, iptables 可以加入、插入或刪除核心包過濾表格 ( ) 中的規則。實際上真正來執行這些過慮規則的是 netfilter(Linux 核心中一個通用架構 ) 及其相關模塊 ( iptables 模塊和 nat 模塊 ), 下面我們一起來看看 netfilter 的工作原理。

二、 原理

netfilter Linux 核心中一個通用架構,它提供了一系列的 " "(tables) ,每個表由若干 " "(chains) 組成,而每條鏈中可以有一條或數條規則 (rule) 組成。我們可以這樣來理解, netfilter 是表的容器,表是鏈的容器,而鏈又是規則的容器

 

系統缺省的表爲 "filter" ,該表中包含了 INPUT FORWARD OUTPUT 3 個鏈。每一條鏈中可以有一條或數條規則,每一條規則都是這樣定義的“如果數據包頭符合這樣的條件,就這樣處理這個數據包”。當一個數據包到達一個鏈時,系統就會從第一條規則開始檢查,看是否符合該規則所定義的條件 : 如果滿足 , 系統將根據該條規則所定義的方法處理該數據包;如果不滿足則繼續檢查下一條規則。最後,如果該數據包不符合該鏈中任一條規則的話,系統就會根據該鏈預先定義的策略 (policy) 來處理該數據包。

 

 

有數據包進入系統時,系統首先根據路由表決定將數據包發給哪一條鏈,則可能有三種情況:

 

 

1. 如果數據包的目的地址是本機,則系統將數據包送往 INPUT 鏈,如果通過規則檢查,則該包被髮給相應的本地進程處理;如果沒通過規則檢查,系統就會將這個包丟掉;

2. 如果數據包的目的地址不是本機,也就是說,這個包將被轉發,則系統將數據包送往 FORWARD 鏈,如果通過規則檢查,則該包被髮給相應的本地進程處理;如果沒通過規則檢查,系統就會將這個包丟掉;

3. 如果數據包是由本地系統進程產生的,則系統將其送往 OUTPUT 鏈,如果通過規則檢查,則該包被髮給相應的本地進程處理;如果沒通過規則檢查,系統就會將這個包丟掉。

 

 

三、 準備工作

 

1. 系統需求

netfilter 要求內核版本不低於 2.3.5 ,在編譯新內核時,要求選擇和 netfilter 相關的項目。這些項目通常都是位於“ Networking options ”子項下。以 2.4.0 內核爲例,我們應該選中的項目有:

[*] Kernel/User netlink socket

[ ] Routing messages

<*> Netlink device emulation [*] Network packet filtering (replaces ipchains)

.......

 

然後,在“ IP: Netfilter Configuration ----> ”選中:

 

<M> Connection tracking (required for masq/NAT)

<M> FTP protocol support

<M> IP tables support (required for filtering/masq/NAT)

<M > limit match support

<M> MAC address match support

<M> Netfilter MARK match support

<M> Multiple port match support

<M> TOS match support

<M> Connection state match support

<M> Packet filtering

<M> REJECT target support

<M> Full NAT

<M> MASQUERADE target support

<M> REDIRECT target support

<M> Packet mangling

<M> TOS target support

<M> MARK target support

<M> LOG target support

<M> ipchains (2.2-style) support

<M> ipfwadm (2.0-style) support

 

其中最後兩個項目可以不選,但是如果你比較懷念 ipchains 或者 ipfwadm ,你也可以將其選中,以便在 2.4 內核中使用 ipchians ipfwadm 。但是需要注意的是, iptables 是和 ipchians/ipfwadm 相對立的,在使用 iptables 的同時就不能同時使用 ipchains/ipfwadm 。編譯成功後,這些模塊文件都位於以下目錄中

/lib/modules/2.4.0/kernel/net/ipv4/netfilter

 

編譯 2.4.0 的新內核時還應該注意要在“ Processor type and features ”中選擇和你的 CPU 相對應的正確的 CPU 選項,否則新內核可能無法正常工作。

 

2. 載入模塊

 

要使用 iptables ,還必須載入相關模塊。可以使用以下命令載入相關模塊:

#modprobe iptable_tables

modprobe 命令會自動載入指定模塊及其相關模塊。 iptables_filter 模塊會在運行時自動載入。

 

三、 語法

 

1. 對鏈的操作

建立一個新鏈 (-N)

刪除一個空鏈 (-X)

改變一個內建鏈的原則 (-P)

列出一個鏈中的規則 (-L)

清除一個鏈中的所有規則 (-F)

歸零 (zero) 一個鏈中所有規則的封包字節 (byte) 記數器 (-Z)

 

2. 對規則的操作

加入 (append) 一個新規則到一個鏈 (-A) 的最後。

在鏈內某個位置插入 (insert) 一個新規則 (-I) ,通常是插在最前面。

在鏈內某個位置替換 (replace) 一條規則 (-R)

在鏈內某個位置刪除 (delete) 一條規則 (-D)

刪除 (delete) 鏈內第一條規則 (-D)

 

3. 指定源地址和目的地址

 

通過 --source/--src/-s 來指定源地址 ( 這裏的 / 表示或者的意思,下同 ) ,通過 --destination/--dst/-s 來指定目的地址。可以使用以下四中方法來指定 ip 地址:

a. 使用完整的域名,如“ www.linuxaid.com.cn ”;

b. 使用 ip 地址,如“ 192.168.1.1

c. x.x.x.x/x.x.x.x 指定一個網絡地址,如“ 192.168.1.0/255.255.255.0 ;

d. x.x.x.x/x 指定一個網絡地址,如“ 192.168.1.0/24 這裏的 24 表明了子網掩碼的有效位數,這是 UNIX 環境中通常使用的表示方法。

缺省的子網掩碼數是 32 ,也就是說指定 192.168.1.1 等效於 192.168.1.1/32

 

4. 指定協議

 

可以通過 --protocol/-p 選項來指定協議,比如 -p tcp

 

5. 指定網絡接口將

 

可以使用 --in-interface/-i --out-interface/-o 來指定網絡接口。需要注意的是,對於 INPUT 鏈來說,只可能有 - i ,也即只會有進入的包;通理,對於 OUTPUT 鏈來說,只可能有 -o ,也即只會有出去的包。只有 FORWARD 鏈既可以有 -i 的網絡接口,也可以有 -o 的網絡接口。我們也可以指定一個當前並不存在的網絡接口,比如 ppp0 ,這時只有撥號成功後該規則纔有效。

 

6. 指定 ip 碎片

 

TCP/IP 通訊過程中,每一個網絡接口都有一個最大傳輸單元 (MTU) ,這個參數定義了可以通過的數據包的最大尺寸。如果一個數據包大於這個參數值時,系統會將其劃分成更小的數個數據包 ( 稱之爲 ip 碎片 ) 來傳輸,而接收方則對這些 ip 碎片再進行重組以還原整個包。

但是再進行包過濾的時候, ip 碎片會導致這樣一個問題:當系統將大數據包劃分成 ip 碎片傳送時,第一個碎片含有完整的包頭信息,但是後續的碎片只有包頭的部分信息,比如源地址,目的地址。因此假如我們有這樣一條規則:

iptables -A FORWARD -p tcp -s 192.168.1.0/24 -d 192.168.2.100 --dport 80 -j ACCEPT

並且這時的 FORWARD 的策略 (policy) DROP 時,系統只會讓第一個 ip 碎片通過,而丟掉其餘的 ip 碎片,因爲第一個碎片含有完整的包頭信息,可以滿足該規則的條件,而餘下的碎片因爲包頭信息不完整而無法滿足規則定義的條件,因而無法通過。

我們可以通過 --fragment/-f 選項來指定第二個及其以後的 ip 碎片,比如以上面的例子爲例,我們可以再加上這樣一條規則來解決這個問題:

iptables -A FORWARD -f -s 192.168.1.0/24 -d 192.168.2.100 -j ACCEPT

但是需要注意的是,現在已經有好多進行 ip 碎片攻擊的實例 ( 比如向 Win98 NT4/SP5,6 Win2K 發送大量的 ip 碎片進行 DoS 攻擊 ) ,因此允許 ip 碎片通過是有安全隱患的,對於這一點我們可以採用 iptables 的匹配擴展來進行限制,但是這又會影響服務質量,我們將在下面討論這個問題。

  

7. 指定非

 

可以在某些選項前加上 ! 來表示非指定值,比如“ -s -! 192.168.1.1/32 ”表示除了 192.168.1.1 以外的 ip 地址,“ -p -! tcp ”表示除了 tcp 以外的協議。

 

8. TCP 匹配擴展

 

通過使用 --tcp-flags 選項可以根據 tcp 包的標誌位進行過濾,該選項後接兩個參數:第一個參數爲要檢查的標誌位,可以是 SYN ACK FIN RST URG PSH 的組合,可以用 ALL 指定所有標誌位;第二個參數是標誌位值爲 1 的標誌。比如你要過濾掉所有 SYN 標誌位爲 1 tcp 包,可以使用以下規則:

iptables -A FORWARD -p tcp --tcp-flags ALL SYN -j DROP

選項 --syn 是以上的一種特殊情況,相當於“ --tcp-flags SYN,RST,ACK SYN ”的簡寫。

 

9. mac 匹配擴展

可以使用 -m 選項來擴展匹配內容。使用 --match mac/-m mac 匹配擴展可以用來檢查 ip 數據包的源 mac 地址。只要在 --mac-source 後面跟上 mac 地址就可以了。比如:

iptables -A FORWARD -m mac --mac-source 00:00:BA:A5:7D:12 -j DROP

需要注意的是一個 ip 包在經過路由器轉發後,其源 mac 地址已經變成了路由器的 mac 地址。

 

10. limit 匹配擴展

 

limit 擴展是一個非常有用的匹配擴展。使用 -m nat 來指定,其後可以有兩個選項:

 

--limit avg: 指定單位時間內允許通過的數據包的個數。單位時間可以是 /second /minute /hour /day 或使用第一個字母,比如 5/second 5/s 是一樣的,都是表示每秒可以通過 5 個數據包,缺省值是 3/hour

 

   --limit-burst number :指定觸發事件的閥值 , 缺省值是 5

 

看起來好像有點複雜,就讓我們來看一個例子:

假設又如下的規則:

iptables -A INPUT -p icmp -m limit --limit 6/m --limit-burst 5 -j ACCEPT

iptables -P INPUT DROP

然後從另一部主機上 ping 這部主機,就會發生如下的現象:

首先我們可以看到前四個包的迴應都很正常,然後從第五個包開始,我們每 10 秒可以收到一個正常的迴應。這是因爲我們設定了單位時間 ( 在這裏是每分鐘 ) 內允許通過的數據包的個數是每分鐘 6 個,也即每 10 秒鐘一個;其次我們又設定了事件觸發閥值爲 5 ,所以我們的前四個包都是正常的,只是從第五個包開始,限制規則開始生效,故只能每 10 秒收到一個正常回應。

假設我們停止 ping 30 秒後又開始 ping ,這時的現象是:

前兩個包是正常的,從第三個包開始丟包,這是因爲在這裏我的允許一個包通過的週期是 10 秒,如果在一個週期內系統沒有收到符合條件的包,系統的觸發值就會恢復 1 ,所以假如我們 30 秒內沒有符合條件的包通過,系統的觸發值就會恢復到 3 ,假如 5 個週期內都沒有符合條件的包通過,系統都觸發值就會完全恢復。不知道你明白了沒有,歡迎你來信討論。

 

11. LOG 目標擴展

 

netfilter 缺省的目標 ( 也就是一旦滿足規則所定義以後系統對數據包的處理方法 ) 有:

ACEEPT :接收並轉發數據包

DORP :丟掉數據包

目標擴展模塊提供了擴展的目標。 LOG 目標提供了記錄數據包的功能。該目標擴展有以下幾個參數:

--log-level :指定記錄信息的級別,級別有 debug info notice warning err crit alert emerg 分別對應 7 0 的數字。其含義請參看 syslog.conf man 手冊。

--log-prefix :後接一個最長爲 30 個字符的字符串,該字符串將出現在每一條日誌的前面。

 

12. REJECT 目標擴展

 

該目標擴展完全和 DORP 標準目標一樣,除了向發送方返回一個“ port unreachable ”的 icmp 信息外。

 

還有其他一些擴展是常用的,如果你想了解可以參考 Packet-Filtering-HOWTO 。當然,最直接獲得幫助的辦法是查看 iptables 的在線幫助,比如想得到關於 mac 匹配擴展的幫助可以執行“ iptables -m mac -help ”命令,想得到 LOG 目標擴展的幫助可以執行“ iptables -j LOG -help ”命令。

四、 iptables 使用實例

 

首先讓我們看一下服務器 / 客戶機的交互原理。服務器提供某特定功能的服務總是由特定的後臺程序提供的。在 TCP/IP 網絡中,常常把這個特定的服務綁定到特定的 TCP UDP 端口。之後,該後臺程序就不斷地監聽( listen) 該端口,一旦接收到符合條件的客戶端請求,該服務進行 TCP 握手後就同客戶端建立一個連接,響應客戶請求。與此同時,再產生一個該綁定的拷貝,繼續監聽客戶端的請求。

 

舉一個具體的例子:假設網絡中有一臺服務器 A(IP 地址爲 1.1.1 .1) 提供 WWW 服務,另有客戶機 B(2.2.2.2) C(3.3.3.3) 。首先,服務器 A 運行提供 WWW 服務的後臺程序(比如 Apache )並且把該服務綁定到端口 80 ,也就是說,在端口 80 進行監聽。當 B 發起一個連接請求時 ,B 將打開一個大於 1024 的連接端口 (1024 內爲已定義端口 ), 假設爲 1037 A 在接收到請求後,用 80 端口與 B 建立連接以響應 B 的請求,同時產生一個 80 端口綁定的拷貝,繼續監聽客戶端的請求。假如 A 又接收到 C 的連接請求(設連接請求端口爲 1071 ),則 A 在與 C 建立連接的同時又產生一個 80 端口綁定的拷貝繼續監聽客戶端的請求。如下所示,因爲系統是以源地址、源端口、目的地址、目的端口來標識一個連接的,所以在這裏每個連接都是唯一的。

 

服務器 客戶端

連接 1 a.b.c.1:80 <=> a.b.c.4:1037

連接 2 a.b.c.1:80 <=> a.b.c.7:1071

 

每一種特定的服務都有自己特定的端口,一般說來小於 1024 的端口多爲保留端口,或者說是已定義端口,低端口分配給衆所周知的服務(如 WWW FTP 等等),從 512 1024 的端口通常保留給特殊的 UNIX TCP/IP 應用程序,具體情況請參考 /etc/services 文件或 RFC1700

 

假設網絡環境如下:某一單位,租用 DDN 專線上網,網絡拓撲如下:

 

+--------------+

| 內部網段 | eth1+--------+eth0 DDN

| +------------|firewall|<===============>Internet

| 198.168.80.0 | +--------+

+--------------+

eth0: 198.199.37.254

eth1: 198.168.80.254

 

以上的 IP 地址都是 Internet 上真實的 IP ,故沒有用到 IP 欺騙。並且,我們假設在內部網中存在以下服務器:

www 服務器: www.yourdomain.com 198.168.80.11

ftp 服務器: ftp.yourdomain.com 198.168.80.12

email 服務器: mail.yourdomain.com 198.168.80.13

 

下面我們將用 iptables 一步一步地來建立我們的包過濾防火牆,需要說明的是,在這個例子中,我們主要是對內部的各種服務器提供保護。

 

1. /etc/rc.d/ 目錄下用 touch 命令建立 firewall 文件,執行 chmod u+x firewll 以更改文件屬性,編輯 /etc/rc.d/rc.local 文件,在末尾加上 /etc/rc.d/firewall 以確保開機時能自動執行該腳本。

 

2. 刷新所有的鏈的規則

#!/bin/sh

 

echo "Starting iptables rules..."

 

#Refresh all chains

 

/sbin/iptables -F

 

3. 我們將首先禁止轉發任何包,然後再一步步設置允許通過的包。

所以首先設置防火牆 FORWARD 鏈的策略爲 DROP

 

/sbin/iptables -P FORWARD DROP

 

4. 設置關於服務器的包過慮規則:

 

在這裏需要注意的是,服務器 / 客戶機交互是有來有往的,也就是說是雙向的,所以我們不僅僅要設置數據包出去的規則,還要設置數據包返回的規則,我們先建立針對來自 Internet 數據包的過慮規則。

 

WWW 服務:服務端口爲 80 ,採用 tcp udp 協議。規則爲: eth0=> 允許目的爲內部網 WWW 服務器的包。

 

###########################Define HTTP packets####################################

 

#Allow www request packets from Internet clients to www servers

/sbin/iptables -A FORWARD -p tcp -d 198.168.80.11 --dport www -i eth0 -j ACCEPT

 

FTP 服務: FTP 服務有點特別,因爲需要兩個端口,因爲 FTP 有命令通道和數據通道。其中命令端口爲 21 ,數據端口爲 20 ,並且有主動和消極兩種服務模式,其消極模式連接過程爲: FTP 客戶端首先向 FTP 服務器發起連接請求,三步握手後建立命令通道,然後由 FTP 服務器請求建立數據通道,成功後開始傳輸數據,現在大多數 FTP 客戶端均支持消極模式,因爲這種模式可以提高安全性。 FTP 服務採用 tcp 協議。規則爲: eth0=> 僅允許目的爲內部網 ftp 服務器的包。

 

############################Define FTP packets#####################################

 

#Allow ftp request packets from Internet clients to Intranet ftp server

/sbin/iptables -A FORWARD -p tcp -d 198.168.80.12 --dport ftp -i eth0 -j ACCEPT

 

 

EMAIL 服務:包含兩個協議,一是 smtp ,一是 pop3 。出於安全性考慮,通常只提供對內的 pop3 服務,所以在這裏我們只考慮針對 smtp 的安全性問題。 smtp 端口爲 21 ,採用 tcp 協議。 eth0=> 僅允許目的爲 email 服務器的 smtp 請求。

 

###########################Define smtp packets####################################

/sbin/iptables -A FORWARD -p tcp -d 198.168.80.13 --dport smtp -i eth0 -j ACCEPT

 

5. 設置針對 Intranet 客戶的過慮規則:

 

在本例中我們的防火牆位於網關的位置,所以我們主要是防止來自 Internet 的攻擊,不能防止來自 Intranet 的攻擊。假如我們的服務器都是基於 linux 的,也可以在每一部服務器上設置相關的過慮規則來防止來自 Intranet 的攻擊。對於 Internet Intranet 客戶的返回包,我們定義如下規則。

 

#############Define packets from Internet server to Intranet#######################

/sbin/iptables -A FORWARD -p tcp -s 0/0 --sport ftp-data -d 198.168.80.0/24 -i eth0 -j ACCEPT

/sbin/iptables -A FORWARD -p tcp -d 198.168.80.0/24 ! -syn -i eth0 -j ACCEPT

/sbin/iptables -A FORWARD -p udp -d 198.168.80.0/24 -i eth0 -j ACCEPT

 

說明:第一條允許 Intranet 客戶採用消極模式訪問 Internet FTP 服務器;第二條接收來自 Internet 的非連接請求 tcp 包;最後一條接收所有 udp 包,主要是針對 oicq 等使用 udp 的服務。

 

6. 接受來自整個 Intranet 的數據包過慮,我們定義如下規則:

 

#############Define packets from Internet server to Intranet server###############

/sbin/iptables -A FORWARD -s 198.168.80.0/24 -i eth1 -j ACCEPT

 

7. 處理 ip 碎片

 

我們接受所有的 ip 碎片,但採用 limit 匹配擴展對其單位時間可以通過的 ip 碎片數量進行限制,以防止 ip 碎片攻擊。

 

###########################Define fregment rule##################################

/sbin/iptables -A FORWARD -f -m limit --limit 100/s --limit-burst 100 -j ACCEPT

 

說明:對不管來自哪裏的 ip 碎片都進行限制,允許每秒通過 100 ip 碎片,該限制觸發的條件是 100 ip 碎片。

 

8. 設置 icmp 包過濾

 

icmp 包通常用於網絡測試等,故允許所有的 icmp 包通過。但是黑客常常採用 icmp 進行攻擊,如 ping of death 等,所以我們採用 limit 匹配擴展加以限制:

 

#################################Define icmp rule##################################

/sbin/iptables -A FORWARD -p icmp -m limit --limit 1/s --limit-burst 10 -j ACCEPT

 

說明:對不管來自哪裏的 icmp 包都進行限制,允許每秒通過一個包,該限制觸發的條件是 10 個包。

 

 

通過以上個步驟,我們建立了一個相對完整的防火牆。只對外開放了有限的幾個端口,同時提供了客戶對 Internet 的無縫訪問,並且對 ip 碎片攻擊和 icmp ping of death 提供了有效的防護手段。以下是完整的腳本文件內容,希望通過這個實例能是對 iptables 的用法有所瞭解:

 

#!/bin/sh

 

echo "Starting iptables rules..."

 

#Refresh all chains

 

/sbin/iptables -F

 

###########################Define HTTP packets####################################

 

#Allow www request packets from Internet clients to www servers

/sbin/iptables -A FORWARD -p tcp -d 198.168.80.11 --dport www -i eth0 -j ACCEPT

 

############################Define FTP packets#####################################

 

#Allow ftp request packets from Internet clients to Intranet ftp server

/sbin/iptables -A FORWARD -p tcp -d 198.168.80.12 --dport ftp -i eth0 -j ACCEPT

 

###########################Define smtp packets####################################

/sbin/iptables -A FORWARD -p tcp -d 198.168.80.13 --dport smtp -i eth0 -j ACCEPT

 

#############Define packets from Internet server to Intranet#######################

/sbin/iptables -A FORWARD -p tcp -s 0/0 --sport ftp-data -d 198.168.80.0/24 -i eth0 -j ACCEPT

/sbin/iptables -A FORWARD -p tcp -d 198.168.80.0/24 ! -syn -i eth0 -j ACCEPT

/sbin/iptables -A FORWARD -p udp -d 198.168.80.0/24 -i eth0 -j ACCEPT

 

#############Define packets from Intranet to Internet###############

/sbin/iptables -A FORWARD -s 198.168.80.0/24 -i eth1 -j ACCEPT

 

#################################Define fregment rule##################################

/sbin/iptables -A FORWARD -f -m limit --limit 100/s --limit-burst 100 -j ACCEPT

 

#################################Define icmp rule##################################

/sbin/iptables -A FORWARD -p icmp -m limit --limit 1/s --limit-burst 10 -j ACCEPT

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章