數據包在用戶空間的狀態

就象前面說的,包的狀態依據IP所包含的協議不同而不同,但在內核外部,也就是用戶空間裏,只有4種 狀態:NEWESTABLISHEDRELATED 和INVALID。它們主要是和狀態匹配一起使用。下面就簡要地介紹以下這幾種狀態:

Table 4-1. 數據包在用戶空間的狀態

State(狀態) Explanation(註釋)
NEW NEW說明這個包是我們看到的第一個 包。意思就是,這是conntrack模塊看到的某個連接第一個包,它即將被匹配了。比如,我們看到一個SYN 包,是我們所留意的連接的第一個包,就要匹配它。第一個包也可能不是SYN包,但它仍會被認爲是NEW狀態。這樣做有時會導致一些問題,但對某些情況是有非常大的幫助的。例如,在 我們想恢復某條從其他的防火牆丟失的連接時,或者某個連接已經超時,但實際上並未關閉時。
ESTABLISHED ESTABLISHED已經注意到兩個方向上 的數據傳輸,而且會繼續匹配這個連接的包。處於ESTABLISHED狀態的連接是非常容 易理解的。只要發送並接到應答,連接就是ESTABLISHED的了。一個連接要從NEW變 爲ESTABLISHED,只需要接到應答包即可,不管這個包是發往防火牆的,還是要由防 火牆轉發的。ICMP的錯誤和重定向等信息包也被看作是ESTABLISHED,只要它們是我 們所發出的信息的應答。
RELATED RELATED是個比較麻煩的狀態。當一 個連接和某個已處於ESTABLISHED狀態的連接有關係時,就被認爲是RELATED的了。換句話說,一個連接要想 是RELATED的,首先要有一個ESTABLISHED的連接。這個ESTABLISHED連接再產生一個主連接之外的連接,這 個新的連接就是RELATED的了,當然前提是conntrack模塊要能理解RELATED。ftp是個很好的例子,FTP-data 連接就是和FTP-control有RELATED的。還有其他的例子,比如,通過IRC的DCC連接。有了這個狀態,ICMP應 答、FTP傳輸、DCC等才能穿過防火牆正常工作。注意,大部分還有一些UDP協議都依賴這個機制。這些協議 是很複雜的,它們把連接信息放在數據包裏,並且要求這些信息能被正確理解。
INVALID INVALID說明數據包不能被識別屬於 哪個連接或沒有任何狀態。有幾個原因可以產生這種情況,比如,內存溢出,收到不知屬於哪個連接的ICMP 錯誤信息。一般地,我們DROP這個狀態的任何東西。

這些狀態可以一起使用,以便匹配數據包。這可以使我們的防火牆非常強壯和有效。以前,我們經常打 開1024以上的所有端口來放行應答的數據。現在,有了狀態機制,就不需再這樣了。因爲我們可以只開放那 些有應答數據的端口,其他的都可以關閉。這樣就安全多了。



Chapter 4. 狀態機制

本章將詳細介紹狀態機制。通讀本章,你會對狀態機制是如何工作的有一個全面的瞭解。我們用一些例 子來進行說明狀態機制。實踐出真知嘛。


4.1. 概述

狀態機制是iptables中特殊的一部分,其實它不應該叫狀態機制,因爲它只是一種連接跟蹤機制。但 是,很多人都認可狀態機制這個名字。文中我也或多或或少地用這個名字來表示和連接跟蹤相同的意思。這 不應該引起什麼混亂的。連接跟蹤可以讓Netfilter知道某個特定連接的狀態。運行連接跟蹤的防火牆稱作 帶有狀態機制的防火牆,以下簡稱爲狀態防火牆。狀態防火牆比非狀態防火牆要安全,因爲它允許我們編寫 更嚴密的規則。

在iptables裏,包是和被跟蹤連接的四種不同狀態有關的。它們是NEWESTABLISHEDRELATEDINVALID。 後面我們會深入地討論每一個狀態。使用--state匹配操作,我們能很容易地控制 “誰或什麼能發起新的會話”。

所有在內核中由Netfilter的特定框架做的連接跟蹤稱作conntrack(譯者注:就是connection tracking 的首字母縮寫)。conntrack可以作爲模塊安裝,也可以作爲內核的一部分。大部分情況下,我們想要,也 需要更詳細的連接跟蹤,這是相比於缺省的conntrack而言。也因爲此,conntrack中有許多用來處理TCP, UDP或ICMP協議的部件。這些模塊從數據包中提取詳細的、唯一的信息,因此能保持對每一個數據流的跟 蹤。這些信息也告知conntrack流當前的狀態。例如,UDP流一般由他們的目的地址、源地址、目的端口和源 端口唯一確定。

在以前的內核裏,我們可以打開或關閉重組功能。然而,自從iptables和Netfilter,尤其是連接跟蹤被 引入內核,這個選項就被取消了。因爲沒有包的重組,連接跟蹤就不能正常工作。現在重組已經整合入 conntrack,並且在conntrack啓動時自動啓動。不要關閉重組功能,除非你要關閉連接跟蹤。

除了本地產生的包由OUTPUT鏈處理外,所有連接跟蹤都是在PREROUTING鏈裏進行處理的,意思就是, iptables會在PREROUTING鏈裏從新計算所有的狀態。如果我們發送一個流的初始化包,狀態就會在OUTPUT鏈 裏被設置爲NEW,當我們收到迴應的包時,狀態就會在PREROUTING鏈裏被設置爲ESTABLISHED。如果第一個包不是本地產生的,那就會在PREROUTING鏈裏被設置爲NEW狀 態。綜上,所有狀態的改變和計算都是在nat表中的PREROUTING鏈和OUTPUT鏈裏完成的。


4.2. conntrack記錄

我們先來看看怎樣閱讀/proc/net/ip_conntrack裏的conntrack記錄。這些記 錄表示的是當前被跟蹤的連接。如果安裝了ip_conntrack模塊,cat /proc/net/ip_conntrack 的顯示類似:

tcp      6 117 SYN_SENT src=192.168.1.6 dst=192.168.1.9 sport=32775 \
     dport=22 [UNREPLIED] src=192.168.1.9 dst=192.168.1.6 sport=22 \
     dport=32775 use=2
     

conntrack模塊維護的所有信息都包含在這個例子中了,通過它們就可以知道某個特定的連接處於什麼狀 態。首先顯示的是協議,這裏是tcp,接着是十進制的6(譯者注:tcp的協議類型代碼是6)。之後的117是 這條conntrack記錄的生存時間,它會有規律地被消耗,直到收到這個連接的更多的包。那時,這個值就會 被設爲當時那個狀態的缺省值。接下來的是這個連接在當前時間點的狀態。上面的例子說明這個包處在狀態 SYN_SENT,這個值是iptables顯示的,以便我們好理解,而內部用的值稍有不同。SYN_SENT說明我們正在觀 察的這個連接只在一個方向發送了一TCP SYN包。再下面是源地址、目的地址、源端口和目的端口。其 中有個特殊的詞UNREPLIED,說明這個連接還沒有收到任何迴應。最後,是希望接收的應答包的信息,他們 的地址和端口和前面是相反的。

連接跟蹤記錄的信息依據IP所包含的協議不同而不同,所有相應的值都是在頭文件linux/include/netfilter-ipv4/ip_conntrack*.h中定義的。IP、TCP、UDP、ICMP協 議的缺省值是在linux/include/netfilter-ipv4/ip_conntrack.h裏定義的。具 體的值可以查看相應的協議,但我們這裏用不到它們,因爲它們大都只在conntrack內部使用。隨着狀態的 改變,生存時間也會改變。

Note

最近patch-o-matic裏有一個新的補丁,可以把上面提到的超時時間也作爲系統變量,這樣我們就 能夠在系統空閒時改變它們的值。以後,我們就不必爲了改變這些值而重編譯內核了。

這些可通過/proc/sys/net/ipv4/netfilter下的一些特殊的系統調用 來改變。仔細看看/proc/sys/net/ipv4/netfilter/ip_ct_*裏的變量吧。

當一個連接在兩個方向上都有傳輸時,conntrack記錄就刪除[UNREPLIED]標誌,然後重置。在末尾有 [ASSURED]的記錄說明兩個方向已沒有流量。這樣的記錄是確定的,在連接跟蹤表滿時,是不會被刪除的, 沒有[ASSURED]的記錄就要被刪除。連接跟蹤表能容納多少記錄是被一個變量控制的,它可由內核中的ip- sysctl函數設置。默認值取決於你的內存大小,128MB可以包含8192條目錄,256MB是16376條。你也可以在 /proc/sys/net/ipv4/ip_conntrack_max裏查看、設置。


4.3. 數據包在用戶空間的狀態

就象前面說的,包的狀態依據IP所包含的協議不同而不同,但在內核外部,也就是用戶空間裏,只有4種 狀態:NEWESTABLISHEDRELATED 和INVALID。它們主要是和狀態匹配一起使用。下面就簡要地介紹以下這幾種狀態:

Table 4-1. 數據包在用戶空間的狀態

State(狀態) Explanation(註釋)
NEW NEW說明這個包是我們看到的第一個 包。意思就是,這是conntrack模塊看到的某個連接第一個包,它即將被匹配了。比如,我們看到一個SYN 包,是我們所留意的連接的第一個包,就要匹配它。第一個包也可能不是SYN包,但它仍會被認爲是NEW狀態。這樣做有時會導致一些問題,但對某些情況是有非常大的幫助的。例如,在 我們想恢復某條從其他的防火牆丟失的連接時,或者某個連接已經超時,但實際上並未關閉時。
ESTABLISHED ESTABLISHED已經注意到兩個方向上 的數據傳輸,而且會繼續匹配這個連接的包。處於ESTABLISHED狀態的連接是非常容 易理解的。只要發送並接到應答,連接就是ESTABLISHED的了。一個連接要從NEW變 爲ESTABLISHED,只需要接到應答包即可,不管這個包是發往防火牆的,還是要由防 火牆轉發的。ICMP的錯誤和重定向等信息包也被看作是ESTABLISHED,只要它們是我 們所發出的信息的應答。
RELATED RELATED是個比較麻煩的狀態。當一 個連接和某個已處於ESTABLISHED狀態的連接有關係時,就被認爲是RELATED的了。換句話說,一個連接要想 是RELATED的,首先要有一個ESTABLISHED的連接。這個ESTABLISHED連接再產生一個主連接之外的連接,這 個新的連接就是RELATED的了,當然前提是conntrack模塊要能理解RELATED。ftp是個很好的例子,FTP-data 連接就是和FTP-control有RELATED的。還有其他的例子,比如,通過IRC的DCC連接。有了這個狀態,ICMP應 答、FTP傳輸、DCC等才能穿過防火牆正常工作。注意,大部分還有一些UDP協議都依賴這個機制。這些協議 是很複雜的,它們把連接信息放在數據包裏,並且要求這些信息能被正確理解。
INVALID INVALID說明數據包不能被識別屬於 哪個連接或沒有任何狀態。有幾個原因可以產生這種情況,比如,內存溢出,收到不知屬於哪個連接的ICMP 錯誤信息。一般地,我們DROP這個狀態的任何東西。

這些狀態可以一起使用,以便匹配數據包。這可以使我們的防火牆非常強壯和有效。以前,我們經常打 開1024以上的所有端口來放行應答的數據。現在,有了狀態機制,就不需再這樣了。因爲我們可以只開放那 些有應答數據的端口,其他的都可以關閉。這樣就安全多了。


4.4. TCP 連接

本節和下面的幾節,我們來詳細討論這些狀態,以及在TCP、UDP和ICMP這三種基本的協議裏怎樣操作它 們。當然,也會討論其他協議的情況。我們還是從TCP入手,因爲它本身就是一個帶狀態的協議,並且具有 很多關於iptables狀態機制的詳細信息。

一個TCP連接是經過三次握手協商連接信息才建立起來的。整個會話由一個SYN包開始,然後是一個 SYN/ACK包,最後是一個ACK包,此時,會話才建立成功,能夠發送數據。最大的問題在於連接跟蹤怎樣控制 這個過程。其實非常簡單。

默認情況下,連接跟蹤基本上對所有的連接類型做同樣的操作。看看下面的圖片,我們就能明白在連接 的不同階段,流是處於什麼狀態的。就如你看到的,連接跟蹤的代碼不是從用戶的觀點來看待TCP連接建立 的流程的。連接跟蹤一看到SYN包,就認爲這個連接是NEW狀態,一看到返回的SYN/ACK包,就認爲連接是 ESTABLISHED狀態。如果你仔細想想第二步,應該能理解爲什麼。有了這個特殊處理,NEW和ESTABLISHED包 就可以發送出本地網絡,且只有ESTABLISHED的連接纔能有迴應信息。如果把整個建立連接的過程中傳輸的 數據包都看作NEW,那麼三次握手所用的包都是NEW狀態的,這樣我們就不能阻塞從外部到本地網絡的連接 了。因爲即使連接是從外向內的,但它使用的包也是NEW狀態的,而且爲了其他連接能正常傳輸,我們不得 不允許NEW狀態的包返回並進入防火牆。更復雜的是,針對TCP連接內核使用了很多內部狀態,它們的定義在 RFC 793 - Transmission Control Protocol的21-23頁。但好在我們在用 戶空間用不到。後面我們會詳細地介紹這些內容。

正如你看到的,以用戶的觀點來看,這是很簡單的。但是,從內核的角度看這一塊還有點困難的。我們 來看一個例子。認真考慮一下在/proc/net/ip_conntrack裏,連接的狀態是如何 改變的。

tcp      6 117 SYN_SENT src=192.168.1.5 dst=192.168.1.35 sport=1031 \
     dport=23 [UNREPLIED] src=192.168.1.35 dst=192.168.1.5 sport=23 \
     dport=1031 use=1
   

從上面的記錄可以看出,SYN_SENT狀態被設置了,這說明連接已經發出一個SYN包,但應答還沒發送過 來,這可從[UNREPLIED]標誌看出。

tcp      6 57 SYN_RECV src=192.168.1.5 dst=192.168.1.35 sport=1031 \
     dport=23 src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031 \
     use=1
   

現在我們已經收到了相應的SYN/ACK包,狀態也變爲SYN_RECV,這說明最初發出的SYN包已正確傳輸,並 且SYN/ACK包也到達了防火牆。 這就意味着在連接的兩方都有數據傳輸,因此可以認爲兩個方向都有相應的 迴應。當然,這是假設的。

tcp      6 431999 ESTABLISHED src=192.168.1.5 dst=192.168.1.35 \
     sport=1031 dport=23 src=192.168.1.35 dst=192.168.1.5 \
     sport=23 dport=1031 use=1
   

現在我們發出了三步握手的最後一個包,即ACK包,連接也就進入ESTABLISHED狀態了。再傳輸幾個數據 包,連接就是[ASSURED]的了。

下面介紹TCP連接在關閉過程中的狀態。

如上圖,在發出最後一個ACK包之前,連接(指兩個方向)是不會關閉的。注意,這只是針對一般的情 況。連接也可以通過發送關閉,這用在拒絕一個連接的時候。在RST包發送之後,要經過預先設定的一段時 間,連接才能斷掉。

連接關閉後,進入TIME_WAIT狀態,缺省時間是2分鐘。之所以留這個時間,是爲了讓數據包能完全通過 各種規則的檢查,也是爲了數據包能通過擁擠的路由器,從而到達目的地。

如果連接是被RST包重置的,就直接變爲CLOSE了。這意味着在關閉之前只有10秒的默認時間。RST包是不 需要確認的,它會直接關閉連接。針對TCP連接,還有其他一些狀態我們沒有談到。下面給出一個完整的狀 態列表和超時值。

Table 4-2. 內部狀態

State Timeout value
NONE 30 minutes
ESTABLISHED 5 days
SYN_SENT 2 minutes
SYN_RECV 60 seconds
FIN_WAIT 2 minutes
TIME_WAIT 2 minutes
CLOSE 10 seconds
CLOSE_WAIT 12 hours
LAST_ACK 30 seconds
LISTEN> 2 minutes

這些值不是絕對的,可以隨着內核的修訂而變化,也可以通過/proc/sys/net/ipv4/netfilter/ip_ct_tcp_*的變量更改。這些默認值都是經過實踐 檢驗的。它們的單位是jiffies(百分之一秒),所以3000就代表30秒。

Note

注意狀態機制在用戶空間裏的部分不會查看TCP包的標誌位(也就是說TCP標誌對它而言是透明 的)。如果我們想讓NEW狀態的包通過防火牆,就要指定NEW狀態,我們理解的NEW狀態的意思就是指SYN包, 可是iptables又不查看這些標誌位。這就是問題所在。有些沒有設置SYN或ACK的包,也會被看作NEW狀態 的。這樣的包可能會被冗餘防火牆用到,但對只有一個防火牆的網絡是很不利的(可能會被攻擊哦)。那我 們怎樣才能不受這樣的包的影響呢?你可以使用未設置SYN的NEW狀態包 裏的命令。還有一個辦法,就是安裝patch-o-matic裏的tcp-window-tracking擴展功能,它可以使防火牆能 根據TCP的一些標誌位來進行狀態跟蹤。


4.5. UDP連接

UDP連接是無狀態的,因爲它沒有任何的連接建立和關閉過程,而且大部分是無序列號的。以某個順序收 到的兩個數據包是無法確定它們的發出順序的。但內核仍然可以對UDP連接設置狀態。我們來看看是如何跟 蹤UDP連接的,以及conntrack的相關記錄。

從上圖可以看出,以用戶的角度考慮,UDP連接的建立幾乎與TCP的一樣。雖然conntrack信息看起來有點 兒不同,但本質上是一樣的。下面我們先來看看第一個UDP包發出後的conntrack記錄。

udp      17 20 src=192.168.1.2 dst=192.168.1.5 sport=137 dport=1025 \
     [UNREPLIED] src=192.168.1.5 dst=192.168.1.2 sport=1025 \
     dport=137 use=1
   

從前兩個值可知,這是一個UDP包。第一個是協議名稱,第二個是協議號,第三個是此狀態的生存時間, 默認是30秒。接下來是包的源、目地址和端口,還有期待之中迴應包的源、目地址和端口。[UNREPLIED]標 記說明還未收到迴應。

udp      17 170 src=192.168.1.2 dst=192.168.1.5 sport=137 \
     dport=1025 src=192.168.1.5 dst=192.168.1.2 sport=1025 \
     dport=137 use=1
   

一旦收到第一個包的迴應,[UNREPLIED]標記就會被刪除,連接就被認爲是ESTABLISHED的,但在記錄裏 並不顯示ESTABLISHED標記。相應地,狀態的超時時間也變爲180秒了。在本例中,只剩170秒了,10秒後, 就會減少爲160秒。有個東西是不可少的,雖然它可能會有些變化,就是前面提過的[ASSURED]。要想變爲 [ASSURED]狀態,連接上必須要再有些流量。

udp      17 175 src=192.168.1.5 dst=195.22.79.2 sport=1025 \
     dport=53 src=195.22.79.2 dst=192.168.1.5 sport=53 \
     dport=1025 [ASSURED] use=1
   

可以看出來,[ASSURED]狀態的記錄和前面的沒有多大差別,除了標記由[UNREPLIED]變成[ASSURED]。如 果這個連接持續不了180秒,那就要被中斷。180秒是短了點兒,但對大部分應用足夠了。只要遇到這個連接 的包穿過防火牆,超時值就會被重置爲默認值,所有的狀態都是這樣的。


4.6. ICMP 連接

ICMP也是一種無狀態協議,它只是用來控制而不是建立連接。ICMP包有很多類型,但只有四種類型有應 答包,它們是回顯請求和應答(Echo request and reply),時間戳請求和應答(Timestamp request and reply),信息請求和應答(Information request and reply),還有地址掩碼請求和應答(Address mask request and reply),這些包有兩種狀態,NEWESTABLISHED 。時間戳請求和信息請求已經廢除不用了,回顯請求還是常用的,比如ping命令就用的到,地址掩碼請 求不太常用,但是可能有時很有用並且值得使用。看看下面的圖,就可以大致瞭解ICMP連接的NEWESTABLISHED狀態了。

如圖所示,主機向目標發送一個回顯請求,防火牆就認爲這個包處於NEW狀態。 目標迴應一個回顯應答,防火牆就認爲包處於ESTABLISHED了。當回顯請求被髮送 時,ip_conntrack裏就有這樣的記錄了:

icmp     1 25 src=192.168.1.6 dst=192.168.1.10 type=8 code=0 \
     id=33029 [UNREPLIED] src=192.168.1.10 dst=192.168.1.6 \
     type=0 code=0 id=33029 use=1
   

可以看到,ICMP的記錄和TCP、UDP的有點區別,協議名稱、超時時間和源、目地址都一樣,不同之處在 於沒有了端口,而新增了三個新的字段:typecodeid。字段type說明ICMP的類型。code說明ICMP的代 碼,這些代碼在附錄ICMP類型裏有說明。id是ICMP包的ID。每個ICMP包被髮送時都被分配一個ID,接受方把同樣的ID 分配給應答包,這樣發送方能認出是哪個請求的應答。

[UNREPLIED]的含義和前面一樣,說明數的傳輸只發生在一個方向上,也就是說未收到應答。再往後,是 應答包的源、目地址,還有相應的三個新字段,要注意的是type和code是隨着應答包的不同而變化的,id和 請求包的一樣。

和前面一樣,應答包被認爲是ESTABLISHED的。然而,在應答包之後,這個ICMP 連接就不再有數據傳輸了。所以,一旦應答包穿過防火牆,ICMP的連接跟蹤記錄就被銷燬了。

以上各種情況,請求被認爲NEW,應答是ESTABLISHED。 換句話說,就是當防火牆看到一個請求包時,就認爲連接處於NEW狀態,當有應答 時,就是ESTABLISHED狀態。

Note

注意,應答包必須符合一定的標準,連接才能被認作established的,每個傳輸類型都是這樣。

ICMP的缺省超時是30秒,可以在/proc/sys/net/ipv4/netfilter/ip_ct_icmp_timeout中修改。這個值是比較合適 的,適合於大多數情況。

ICMP的另一個非常重要的作用是,告訴UDP、TCP連接或正在努力建立的連接發生了什麼,這時ICMP應答 被認爲是RELATED的。主機不可達和網絡不可達就是這樣的例子。當試圖連接某臺機 子不成功時(可能那臺機子被關上了),數據包所到達的最後一臺路由器就會返回以上的ICMP信息,它們就 是RELATED的,如下圖:

我們發送了一個SYN包到某一地址,防火牆認爲它的狀態是NEW。但是,目標網絡 有問題不可達,路由器就會返回網絡不可達的信息,這是RELATED的。連接跟蹤會認 出這個錯誤信息是哪個連接的,連接會中斷,同時相應的記錄刪除會被刪除。

當UDP連接遇到問題時,同樣會有相應的ICMP信息返回,當然它們的狀態也是RELATED ,如下圖:

我們發送一個UDP包,當然它是NEW的。但是,目標網絡被一些防火牆或路由器所 禁止。我們的防火牆就會收到網絡被禁止的信息。防火牆知道它是和哪個已打開的UDP連接相關的,並且把 這個信息(狀態是RELATED)發給它,同時,把相應的記錄刪除。客戶機收到網絡被 禁止的信息,連接將被中斷。


4.7. 缺省的連接操作

有時,conntrack機制並不知道如何處理某個特殊的協議,尤其是在它不瞭解這個協議或不知道協議如何 工作時,比如,NETBLT,MUX還有EGP。這種情況下,conntrack使用缺省的操作。這種操作很象對UDP連接的 操作,就是第一個包被認作NEW,其後的應答包等等數據都是 ESTABLISHED

使用缺省操作的包的超時值都是一樣的,600秒,也就是10分鐘。當然,這個值可以通過/proc/sys/net/ipv4/netfilter/ip_ct_generic_timeout更改,以便適應你的通信 量,尤其是在耗時較多、流量巨大的情況下,比如使用衛星等。


4.8. 複雜協議和連接跟蹤

有些協議比其他協議更復雜,這裏複雜的意思是指連接跟蹤機制很難正確地跟蹤它們,比如,ICQ、IRC 和FTP,它們都在數據包的數據域裏攜帶某些信息,這些信息用於建立其他的連接。因此,需要一些特殊的 helper來完成工作。

下面以FTP作爲例子。FTP協議先建立一個單獨的連接——FTP控制會話。我們通過這個連接發佈命令,其 他的端口就會打開以便傳輸和這個命令相關的數據。這些連接的建立方法有兩種:主動模式和被動模式。先 看看主動模式,FTP客戶端發送端口和IP地址信 息給服務器端,然後,客戶端打開這個端口,服務器端從它自己的20端口(FTP-Data端口號)建立與這個端 口的連接,接着就可以使用這個連接發送數據了。

問題在於防火牆不知道這些額外的連接(相對於控制會話而言),因爲這些連接在建立時的磋商信息都 在協議數據包的數據域內,而不是在可分析的協議頭裏。因此,防火牆就不知道是不是該放這些從服務器到 客戶機的連接過關。

解決的辦法是爲連接跟蹤模塊增加一個特殊的helper,以便能檢測到那些信息。這樣,那些從FTP服務器 到客戶機的連接就可以被跟蹤了,狀態是RELATED,過程如下圖所示:

被動FTP工作方式下,data連接的建立過程和主動FTP的相反。客戶機告訴服務器需要某些數據,服務器 就把地址和端口發回給客戶機,客戶機據此建立連接接受數據。如果FTP服務器在防火牆後面,或你對用戶 限制的比較嚴格,只允許他們訪問HTTP和FTP,而封閉了其他所有端口,爲了讓在Internet是的客戶機能訪 問到FTP,也需要增加上面提到的helper。下面是被動模式下data連接的建立過程:

有些conntrack helper已經包含在內核中,在寫這篇文章時,FTP和IRC已有了相應的conntrack helper。如果在內核裏沒有你想要的helper,可以到iptables用戶空間的patch-o-matic目錄中看看,那裏 有很多的helper,比如針對ntalk或H.323協議的等等。如果沒找到,還有幾個選擇:可以查查iptables的 CVS,或者聯繫Netfilter-devel問問有沒有你要的。還不行的話,只有你 自己寫了,我可以給你介紹一篇好文章,Rusty Russell's Unreliable Netfilter Hacking HOW-TO,連接放在附錄裏其他資源和 鏈接

Conntrack helper即可以被靜態地編譯進內核,也可以作爲模塊,但要用下面的命令裝載:

modprobe ip_conntrack_*
   

注意連接跟蹤並不處理NAT,因此要對連接做NAT就需要增加相應的模塊。比如,你想NAT並跟蹤FTP連 接,除了FTP的相應模塊,還要有NAT的模塊。所有的NAT helper名字都是以ip_nat_開頭的,這是一個命名 習慣:FTP NAT helper叫做ip_nat_ftp,IRC的相應模塊就是ip_nat_irc。conntrack helper 的命名也遵循 一樣的習慣:針對IRC的conntrack helper叫ip_conntrack_irc,FTP的叫作ip_conntrack_ftp。


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