防火牆軟體Netfilter之包過濾技術(轉)

post0發表於2007-08-10
防火牆軟體Netfilter之包過濾技術(轉)[@more@]

如果您不知道什麼是IP地址、網路地址、網路掩碼、路由或者DNS,那麼,請先閱讀相關的網路基礎書籍。

1.什麼是包過濾(Packet Filter)?

包過濾技術就是利用一些軟體來檢視收到包的頭部,然後決定整個包的命運。要麼DROP這個包(例如丟棄這個包,就像沒有收到一樣);要麼Accept這個包;或者更復雜的動作。在Linux下,包過濾被編譯到核心中。

2.為什麼要用包過濾

控制:

能夠允許某些型別的包透過,或者不允許某些型別的包透過。例如,包的頭部含有目的地址的資訊,因此,您可以設定過濾規則禁止網路內部的包到達某些外部的網路地址。舉個例項,當你用netscape瀏覽Dilbert文件時,在它的頁面上會出現來自doubleclick.net的煩人廣告,讓包過濾禁止任何去或者來自doubleclick.net的包就可以解決問題了。

安全:

如何在混亂的Internet和您的有序的網路之間通訊?設定了防火牆來把守您的大門是十分必要的。例如,您可以允許任何包出去,但是對著名的“Ping of Death”(來自外部的攻擊者)感到焦慮。又例如,您不允許外部telnet到內部的機器(儘管每個使用者都有密碼)。等等,都可以透過設定規則解決。

警覺:

有時候一臺配置不好的內部機器向外面噴湧發包。包過濾能夠及時向網路管理員報告此類異常,這樣,管理員就能夠做出相應的行動,以防不測。

3.Linux包過濾的發展史

l Ipfw 1994, coming from BSD, 核心2.0,工具ipfwadm

l Ipchains 1998, based on the ipfw, 核心 2.2,工具ipchains

l Netfilter 1999, based on the ipchains, 核心2.3.15~2.4, 工具iptables

(包過濾原始碼直接嵌入在核心中,工具iptables作為一個模組,可以嵌入,也可以不)

4.Iptables

新一代的工具,比ipchains和ipfwadm更加強大,對IPv6的支援更好。

5.Iptables快速指南

大多數人只有一個單獨的PPP連線到Internet,但是不想任何人訪問他們的內部網路或者放火牆,可以如下設定:

## Insert connection-tracking modules (not needed if built into kernel).

# insmod ip_conntrack

# insmod ip_conntrack_ftp

## Create chain which blocks new connections, except if coming from inside.

# iptables -N block

# iptables -A block -m state --state ESTABLISHED,RELATED -j ACCEPT

# iptables -A block -m state --state NEW -i ! ppp0 -j ACCEPT

# iptables -A block -j DROP

## Jump to that chain from INPUT and FORWARD chains.

# iptables -A INPUT -j block

# iptables -A FORWARD -j block

6.包如何透過netfilter

核心在過濾表中維持了3個規則列表,這些列表叫做firewall chains。這3個chains分別叫做INPUT, OUTPUT 和FORWARD。如下圖:

Incoming /--------- Outgoing

-----------&gt[Routing ]---&gt|FORWARD|-------------&gt

[Decision] \_____/ ^

| |

v ____

___ /

/ |OUTPUT|

|INPUT| \____/

\___/ ^

| |

-----&gt Local Process -----------

當包經過相應的chain時,這個chain將決定這個包的命運。如果chain認為DROP,就丟棄這個包;如果認為ACCEPT就繼續在圖中旅行。每一個chain是眾多規則的檢查表。規則的格式為:“如果包頭部看起來象某個東西,然後對這個包做某個動作”。如果一條規則與包頭部不匹配,繼續檢查 chain中的下一條規則。一旦找到匹配的,執行相應的動作。否則,一條匹配的都沒有,就檢查chain的安全策略。通常是DROP。過程如下:

l 當一個包到達(如乙太網介面),核心首先檢查包的目的地址,這叫做“路由”

l 如果包的目的地址是本機,包將繼續在上圖中旅行,到達INPUT chain,如果透過了這個chain,那麼任何需要這個包的程式都可以收到

l 目的地不是本機,如果核心不允許包轉發,或者不知道如何轉發,DROP這個包;如果核心允許轉發,並且包需要經過另一塊網路介面(在您的機器上至少有兩個網路介面),那麼包將在圖中旅行到FORWARD chain,如果透過這個chain,包就可以送出了

l 本機程式發出的包必須經過OUTPUT chain,如果能夠透過這個chain,那麼這個包就可以送到相應的網路介面併發出

7.使用iptables

iptables有一個非常詳細的幫助檔案(man iptables),跟ipchains有很多類似之處。

下面列出管理chain的一些引數:

Create a new chain (-N). 產生一個新的chain

Delete an empty chain (-X). 刪除一個空的chain

Change the policy for a built-in chain. (-P). 修改安全策略

List the rules in a chain (-L). 列出chain的規則

Flush the rules out of a chain (-F). 清空所有規則

Zero the packet and byte counters on all rules in a chain (-Z). 所有規則包和位元組數清零

管理一個chain內部的規則:

Append a new rule to a chain (-A). 加入一個新的規則

Insert a new rule at some position in a chain (-I). 在一個chain的某個位置加入新的規則

Replace a rule at some position in a chain (-R). 在一個chain的某個位置替換規則

Delete a rule at some position in a chain (-D). 在一個chain的某個位置刪除規則

Delete the first rule that matches in a chain (-D). 刪除與chain匹配的第一條規則

8.計算機啟動

iptables可以作為一個模組(iptable_filter.o),當你執行iptables時候自動裝載,或者永久的編譯到核心中。

在任何iptables命令執行之前,三個chain的預設安全策略是“ACCEPT”。可以修改FORWARD chain的策略,把iptable_filter模組的選項中的forward=0。

9.單條規則的操作

用前面介紹的 –A(append) –D(delete) –I(insert) –R(replace)。

每一條規則首先描述包需要滿足的條件,然後描述相應的動作(目標)。例如,如果你想DROP掉所有的來自地址127.0.0.1的ICMP包。因此,規則的條件為:協議ICMP、源地址127.0.0.1;規則的目標為DROP。

127.0.0.1是一個loopback介面,即使你沒有真正的網路介面都可以用。你可以用ping命令來產生這樣的包,用於測試。例如:

# ping -c 1 127.0.0.1

PING 127.0.0.1 (127.0.0.1): 56 data bytes

64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.2 ms

--- 127.0.0.1 ping statistics ---

1 packets transmitted, 1 packets received, 0% packet loss

round-trip min/avg/max = 0.2/0.2/0.2 ms

現在加上規則:

# iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP

再試試:

# ping -c 1 127.0.0.1

PING 127.0.0.1 (127.0.0.1): 56 data bytes

--- 127.0.0.1 ping statistics ---

1 packets transmitted, 0 packets received, 100% packet loss

您可以看到這樣的包已經被過濾掉了。

-A選項選擇chain,我們設為INPUT chain;-s 源地址,我們設為127.0.0.1;-p協議,我們設為ICMP;-j 表示jump,我們設為jump到DROP。

我們也可以刪除規則。有兩種方法:

第一種方法是既然我們知道他是input chain中的第一條規則,可以用下面的命令:

# iptables -D INPUT 1

刪除規則1;

第二種方法是匹配-A選項,用-D選項代替。這適用於規則非常多,不容易記住編號的情況,例如要刪除上面的規則:

# iptables -D INPUT -s 127.0.0.1 -p icmp -j DROP

10. 過濾規則的描述

l 描述源和目的IP地址

源地址(-s 或者—source或者—src)目的地址(-d或者—destination或者--dst)。一般是用名字如“localhost”或者;或者用IP地址如127.0.0.1。

有時候需要描述一組地址,例如199.95.207.0/24或者199.95.207.0/255.255.255.0用來描述從199.95.207.0到199.95.207.255的所有地址。/後面是網路掩碼或網路位數。/0表示任何地址。例如:

# iptables -A INPUT -s 0/0 -j DROP

表示DROP掉所有收到的包。

l 反符號!

用符號!可以表示相反的意思。例如:

-s ! localhost 表示任何不是來自localhost的包。

-p ! TCP 表示任何不是TCP的協議。

l 描述協議

-p 協議名(如TCP)

l 描述介面

-i選項表示in-interface;-o選項表示out-interface。分別表示包將要到達或者離開的屋裡裝置。你可以用命令ifconfig來檢視網路介面。

INPUT chain不需要輸出介面,所以他的-o 選項的內容將會被忽略。同理,OUTPUT chain不需要-I 選項的內容。

僅僅只有FORWARD chain同時需要輸出和輸入選項,即-I 和 –o 都有用。

描述一個並不存在的網路介面是可以得,這特別適用於撥號上網的情況。符號+表示匹配,例如:-i ppp+表示所有的PPP介面。

!符號也可以用在介面中

l 描述分片

當一個包在傳輸過程中由於大於所經過的網路的最大傳輸單元(包的長度太大),將會分片,分成很多小的分片發出。在另一端再進行重組。關於分段的問題的是第一個分片可以很好的檢查(IP + TCP/UDP/ICMP),但是後續的分片只有IP,沒有上一層的資訊。這對於過濾規則是不可能的。

因而,讓我們看看過濾規則怎麼處理分片。第一個分片跟普通的包處理沒有任何區別,但是第二個以及以後的分片將由於缺少資訊而不會與規則匹配。例如:

規則-p TCP --sport www將不會匹配任何分片(除了第一個分片)。同樣規則-p TCP --sport ! www也不會匹配任何分片(除了第一個)。

但是可以使用-f 選項來描述規則,以適用於第二個和以後的分片。通常是讓第二個和以後的分片透過,因為過濾規則適用於第一個分片,如果第一個分片沒有透過,他的分片最終將不會重組。但是要小心大量的分片會崩掉你的網路或機器。

例如,下面的規則將會drop所有到192.168.1.1的分片:

# iptables -A OUTPUT -f -d 192.168.1.1 -j DROP

l iptables的可擴充套件性

iptables是可以擴充套件的,這就是說意味著核心和iptables工具都可以擴充套件以提供新的特性。

核心擴充套件位於核心的模組子目錄,例如/lib/modules/2.3.15/net。需要你手工加入這些模組。

Iptables程式擴充套件位於目錄/usr/local/lib/iptables/。

為了獲得擴充套件的幫助,用選項(-p、-m、-j)來裝載他並且後跟-h,例如:

# iptables -p tcp --help

l TCP擴充套件

如果-p tcp被描述,TCP擴充套件將會自動裝載。下面的選項將生效(對分片無效)

--tcp-flags

一系列的標誌,分為兩個串,第一個串表示哪些標誌是要檢查的;第二個串表示哪些標誌是1(其他則為0)。

例如:

# iptables -A INPUT --protocol tcp --tcp-flags ALL SYN,ACK -j DENY

表示ALL(SYN,ACK,FIN,RST,URG,PSH')的標誌都要被檢查,但是隻有設定了SYN和ACK的才匹配。

--syn

等同於--tcp-flags SYN,RST,ACK SYN (100)

--source-port 或者 --sport

描述源埠,要麼用數字,用麼用/etc/services檔案中的名字。可以用m:n來表示一組埠。

--destination-port 或者 –dport

描述目的埠

--tcp-option

檢查一個包是否有相應的tcp選項,如果沒有的話,包將被drop掉。

l TCP標記的一個解釋

有時候只允許一個單向的TCP連線。例如,你只需要訪問外部的WWW的伺服器,而不允許外部訪問你內部的WWW伺服器。樸素的方法是阻塞所有從你的伺服器發出的包,但是TCP連線需要一個雙向的交流。解決的方法是隻需要阻塞請求連線的包。這些包叫做SYN包。透過阻塞這些包,我們可以達到上面的目的。

標誌—syn將被使用。他僅僅適用於TCP協議。例如:

-p TCP -s 192.168.1.1 --syn

這條規則描述所有從192.168.1.1發起的連線。

l UDP擴充套件

如果-u udp 被描述,所有擴充套件自動裝載。他提供與TCP類似的選項--source-port, --sport, --destination-port, --dport。

l ICMP擴充套件

如果選項-p icmp被描述,所有的擴充套件自動裝載。他只提供一個選項:

--icmp-type

看名字就知道是指型別,具體的名字參看-p icmp –help提供的幫助資訊。

l 其他匹配擴充套件

這些選項可以用-m來啟動。

Mac

這個模組可以用-m mac或者--match mac來啟動。用於匹配輸入包的MAC地址,因此之用於PREROUTING and INPUT chains。他只提供一個選項:--mac-source

例如:--mac-source 00:60:08:91:CC:B7

limit

可以用-m limit或者--match limit來啟動。用於限制機器,如壓縮log資訊等等。

Owner

只用於output chain中,並且有些包沒有owner(如icmp包),因而沒有匹配。

--uid-owner userid 包的產生程式的有效使用者id等於userid

--uid-owner groupid包的產生程式的有效組id等於groupid

--pid-owner processid 包的產生程式的程式的id等於processid

--sid-owner sessionid 包的產生程式的session id 等於sessionid

unclean

提供隨機的安全檢查

l 狀態匹配

最有用的匹配規則是由狀態擴充套件來提供的。因此推薦用模組ip_conntrack。描述-m state允許一個附加的—state選項。是一個逗號分開的狀態列表,這些狀態有:

NEW

包建立了一個新的連線

ESTABLISHED

包屬於一個已經存在地連線

RELATED

一個包與某個連線有關,但是不屬於這個連線。

INVALID

包無法定義,通常這些包會被drop

11. 目標描述

現在我們已經知道了怎麼檢查包,下一步就是決定對匹配的包做什麼動作。這一步叫做規則的目標。

兩種基本的目標是DROP和ACCEPT。我們已經很清楚了。

但是還有的目標:擴充套件、使用者定義的chains。

使用者定義的chains

iptables從ipchains繼承的一個重要的特性就是使用者可以自定義新的chains(除了3個內建的INPUT, FORWARD和OUTPUT)。

當一個包在使用者定義的chain中進行規則匹配時,將遍歷chain中的所有規則。直到找到匹配。

下面考慮兩個2個chain:INPUT(內建)、test(使用者定義)。

`INPUT' `test'

---------------------------- ----------------------------

| Rule1: -p ICMP -j DROP | | Rule1: -s 192.168.1.1 |

|--------------------------| |--------------------------|

| Rule2: -p TCP -j test | | Rule2: -d 192.168.1.1 |

|--------------------------| ----------------------------

| Rule3: -p UDP -j DROP |

----------------------------

假設一個包來自192.168.1.1,其目的地址是1.2.3.4。他首先進入INPUT chain,規則1不匹配。規則2匹配並且其目標是test,因此下一個檢查的規則是test的第一個規則。規則1匹配,但是沒有描述目標,因此規則2被檢查。規則2不匹配,到達chain的末尾。於是返回INPUT chain,這裡我們已經檢查過規則2,於是檢查規則3,不匹配。因此包的檢查路徑是:

v __________________________

`INPUT' | / `test' v

------------------------|--/ -----------------------|----

| Rule1 | /| | Rule1 | |

|-----------------------|/-| |----------------------|---|

| Rule2 / | | Rule2 | |

|--------------------------| -----------------------v----

| Rule3 /--+___________________________/

------------------------|---

v

使用者定義的chains也可以把目標設為使用者定義的chains。但是不要形成環。

Iptables的擴充套件:新的目標

新的目標包括一個核心模組和一個可選的擴充套件選項(新的命令選項)。在netfilter的發行版本中有下面的幾個擴充套件:

LOG

這個模組使得核心可以記錄匹配的包的日誌。

REJECT

這個模組基本等同於DROP,但是有一點不同。傳送方將送出一個ICMP報文:“port unreachable”。注意以下情況不傳送:

l 被過濾的包本身是一個ICMP差錯控制或未知報文;

l 第二塊及以後的分片

l 最近已經送出了許多ICMP差錯控制報文到那個目標

特殊的內建目標

有兩個特殊的內建目標:RETURN 和QUEUE

RETURN相當於到達chain的末尾。對於一個內建的chain來說,執行相應的策略。對於自定義的,返回前一條chain。

QUENE是一個特殊的目標。他將包放到使用者空間等待處理。需要兩個額外的部件:

l 佇列處理器(處理包在核心和使用者空間的流通)

l 使用者空間的應用程式(接受包、操作包)

標準的佇列處理器模組ip_queue。

下面是一個例子:

# modprobe iptable_filter

# modprobe ip_queue

# iptables -A OUTPUT -p icmp -j QUEUE

有了這條規則,本地產生的外出ICMP包將流到ip_queue模組,然後他再將包送到使用者空間的應用程式。如果沒有使用者空間的應用程式等待這個包,DROP。

怎麼寫使用者空間的應用程式呢?用libipq API。他是和iptables一起釋出的。程式例子在CVS中的testsuide工具裡。

ip_queue的狀態可以透過下面的命令檢視:

/proc/net/ip_queue

佇列的最大長度可以用下面的命令來控制:

/proc/sys/net/ipv4/ip_queue_maxlen

預設值是1024。

12. 對整個chain的操作

l 建立一個新的chain

假設我們要建立一個名字為test的chain:

# iptables -N test

是不是很簡單?現在你就可以按照我上面所說的加規則了。

l 刪除一個chain

同樣的簡單。用 –X 或者 –delete-chain選項。

# iptables -X test

注意,刪除chain之前,chain必須為空,即沒有規則。三個內建chain不能被刪除。如果不加名字就刪除所有可以刪除的chain。

l 清空chain中的所有規則

用-F選項

# iptables -F FORWARD

如果沒有chain的名字,將清空所有的chain的所有規則。

l 列出一個chain中的所有規則

用 –L 或者 –list選項

refcnt列是指使用者定義的chain的規則數。只有refcnt = 0,chain才可以刪除。

另外附加選項 –n 可以避免域名解析,只有IP地址。

-v 選項顯示更多細節。

-x 選項顯示具體數字,不用K、M、G等表示1000、1000000、1000000000。

l 記數復位

用 –Z 選項。

例如:

# iptables -L FORWARD

# iptables -Z FORWARD

在上面的兩條命令之間,可能會有一些包透過。因此可以將他們合在一起,復位記數。

l 設定策略

當一個包沒有找到合適的規則匹配,這時候策略將會決定包的命運。僅僅只有3個內建的chain才有策略。因為當一個包到達使用者定義的chain的末尾,會返回前一個chain。

策略可以為ACCEPT或者DROP,例如:

# iptables -P FORWARD DROP

13. 使用ipchains和ipfwadm

這是對於老使用者熟悉了以前的,又不想學習iptables的。有兩個模組ipchains.o 和ipfwadm.o。

只要插入相應的模組就可以了。

14. 混合NAT和包過濾技術

在應用包過濾技術不用考慮NAT的存在,二者結合很好。

關於NAT,將在下一篇中描述。

15. 包過濾技術的設計建議

在電腦保安領域,一種說法是阻塞所有的東西,然後當需要時才開啟一些小洞小坑。就像古羅馬的競技場。Ipchains的作者強烈推薦這種方法。

不執行你不需要的服務!!

如果執行防火牆,開始時阻塞所有的包,然後再慢慢地讓需要的包透過。

建議將包過濾與tcp-wrappers、代理技術、路由檢驗結合起來。

強烈建議跟蹤連線:需要裝載模組ip_conntrack.o。例如,下列命令:

# iptables -N no-conns-from-ppp0

# iptables -A no-conns-from-ppp0 -m state --state ESTABLISHED,RELATED -j ACCEPT

# iptables -A no-conns-from-ppp0 -m state --state NEW -i ! ppp0 -j ACCEPT

# iptables -A no-conns-from-ppp0 -i ppp0 -m limit -j LOG --log-prefix "Bad packet from ppp0:"

# iptables -A no-conns-from-ppp0 -i ! ppp0 -m limit -j LOG --log-prefix "Bad packet not from ppp0:"

# iptables -A no-conns-from-ppp0 -j DROP

# iptables -A INPUT -j no-conns-from-ppp0

# iptables -A FORWARD -j no-conns-from-ppp0

細細體會之

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8225414/viewspace-940730/,如需轉載,請註明出處,否則將追究法律責任。

相關文章