iptables的狀態機制

狀態機制

            狀態機制是iptables中較爲特殊的一部分,這也是iptables和比較老的ipchains的一個比較大的區別之一,運行狀態機制(鏈接跟蹤)的防火牆稱做帶有狀態機制的防火牆,如下簡稱爲狀態防火牆。狀態防火牆比非狀態防火牆要安全,由於它容許咱們編寫更嚴密的規則。安全

            在iptables上一共有四種狀態,分別被稱爲NEW、ESTABLISHED、INVALID、RELATED,這四種狀態對於TCP、UDP、ICMP三種協議均有效。下面,咱們來分別闡述四種狀態的特性。服務器

  1. NEW:NEW說明這個包是咱們看到的第一個包。意思就是,這是conntrack模塊看到的某個鏈接的第一個包,它即將被匹配了。好比,咱們看到一個SYN 包,是咱們所留意的鏈接的第一個包,就要匹配它。
  2. ESTABLISHED: ESTABLISHED已經注意到兩個方向上的數據傳輸,並且會繼續匹配這個鏈接的包。處於ESTABLISHED狀態的鏈接是很是容易理解的。只要發送並接到應答,鏈接就是ESTABLISHED的了。一個鏈接要從NEW變爲ESTABLISHED,只須要接到應答包便可,無論這個包是發往防火牆的,仍是要由防火牆轉發的。ICMP的錯誤和重定向等信息包也被看做是ESTABLISHED,只要它們是咱們所發出的信息的應答。
  3. RELATED: RELATED是個比較麻煩的狀態。當一個鏈接和某個已處於ESTABLISHED狀態的鏈接有關係時,就被認爲是RELATED的了。換句話說,一個鏈接要想是RELATED的,首先要有一個ESTABLISHED的鏈接。這個ESTABLISHED鏈接再產生一個主鏈接以外的鏈接,這個新的鏈接就是 RELATED的了,固然前提是conntrack模塊要能理解RELATED。ftp是個很好的例子,FTP-data 鏈接就是和FTP-control有關聯的,若是沒有在iptables的策略中配置RELATED狀態,FTP-data的鏈接是沒法正確創建的,還有其餘的例子,好比,經過IRC的DCC鏈接。有了這個狀態,ICMP應答、FTP傳輸、DCC等才能穿過防火牆正常工做。注意,大部分還有一些UDP協議都依賴這個機制。這些協議是很複雜的,它們把鏈接信息放在數據包裏,而且要求這些信息能被正確理解。
  4. INVALID:INVALID說明數據包不能被識別屬於哪一個鏈接或沒有任何狀態。有幾個緣由能夠產生這種狀況,好比,內存溢出,收到不知屬於哪一個鏈接的ICMP錯誤信息。通常地,咱們DROP這個狀態的任何東西,由於防火牆認爲這是不安全的東西。

            每一個狀態相對於不一樣的第四層協議來說,稍微有些區別,對於TCP協議來講,當防火牆收到第一個數據包,也就是SYN報文時,將該會話標記爲NEW狀態,在系統的/proc/net/目錄下,能夠查閱ip_conntrack,這是在內存空間裏存放防火牆當前狀態表的臨時文件,對於NEW狀態的記錄以下:網絡

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]標誌看出,當服務器端迴應了SYN/ACK包後,狀態表改寫爲:tcp

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三次握手的隨後一個報文ACK包也到達了防火牆,防火牆上的狀態表變成了:spa

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

            如今,咱們來看看UDP協議的狀態描述方法,從協議自己的特性來看,UDP鏈接是無狀態的,由於它沒有任何的鏈接創建和關閉過程。以某個順序收到的兩個數據包是沒法肯定它們的發出順序的。但內核仍然能夠對UDP鏈接設置狀態。咱們來看看是如何跟蹤UDP鏈接的,以及在覈心目錄 /proc/net/ip_conntrack的相關記錄。code

            當第一個UDP的數據包到達防火牆後,防火牆在他的狀態表中留下了這樣的記錄:orm

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

            UNREPLIED表明這是一個狀態爲NEW的數據包,當這條鏈接的迴應數據包到達防火牆後,防火牆當即將修改這條狀態記錄:ip

udp 17 160 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被刪除了,這表明如今防火牆已經創建了一條UDP協議的會話,但這裏並無象TCP協議那樣顯示 ESTABLISHED標記,這是TCP的狀態記錄和UDP的狀態記錄稍微不一樣的一個地方,固然,還有一個地方須要注意,在測試中,還須要有一些數據包通過,防火牆纔會將狀態記錄改寫成:內存

udp 17 179 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 [ASSURED] use=1

            ASSURED狀態表示當前有數據在進行傳輸,表面當前鏈接的狀態是ACTIVE的。若是,在這個狀態下數據中止了傳輸,則這條記錄會有一個計時器,也就是記錄中的第三個字段,上面這條記錄的第三個字段是179,表明當前的ASSURED狀態還可以保持179秒,若是還有新的數據包通過,那麼計時器會被從新設置成缺省的180秒,若是在180秒內都沒有流量,那麼這條狀態記錄就會從狀態表中被刪除。

 

 

            最後,咱們在來看看Linux kernel是如何標示ICMP協議的狀態的,ICMP也是一種無狀態協議,它只是用來控制而不是創建鏈接。

            ICMP包有不少類型,但只有四種類型有應答包,它們是回顯請求和應答(Echo request and reply),時間戳請求和應答(Timestamp request and reply),信息請求和應答(Information request and reply),還有地址掩碼請求和應答(Address mask request and reply),這些包有兩種狀態,NEW和ESTABLISHED 。時間戳請求和信息請求已經廢除不用了,回顯請求仍是經常使用的,好比ping命令就用的到,地址掩碼請求不太經常使用,可是可能有時頗有用而且值得使用。看看下面的圖,就能夠大體瞭解ICMP鏈接的NEW和ESTABLISHED狀態了。

            如圖所示,主機向目標發送一個回顯請求,防火牆就認爲這個包處於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的有點區別,協議名稱、超時時間和源、目地址都同樣,不一樣之處在於沒有了端口,而新增了三個新的字段:type,code和id。字段type說明ICMP的類型。code說明ICMP的代碼,這些代碼在附錄ICMP類型裏有說明。id是 ICMP包的ID。每一個ICMP包被髮送時都被分配一個ID,接受方把一樣的ID 分配給應答包,這樣發送方能認出是哪一個請求的應答。

            [UNREPLIED] 的含義和前面同樣,說明數的傳輸只發生在一個方向上,也就是說未收到應答。再日後,是應答包的源、目地址,還有相應的三個新字段,要注意的是type和 code是隨着應答包的不一樣而變化的,id和請求包的同樣。和前面同樣,應答包被認爲是ESTABLISHED的。然而,在應答包以後,這個ICMP 鏈接就再也不有數據傳輸了。因此,一旦應答包穿過防火牆,ICMP的鏈接跟蹤記錄就被銷燬了。所以,要想在/proc/ip_conntrack文件中抓到 ICMP協議的狀態記錄實在不是一件容易的事。您能夠用以下的命令來嘗試獲取這些記錄:

#cat /proc/net/ip_conntrack | grep icmp

            若是沒有輸出,那麼就不停的重複這個命令,直到發現icmp的記錄爲止。

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

            state匹配:state匹配在防火牆配置過程當中很是重要的,若是沒有state的配置,那麼須要配置雙向的規則才能知足通信的須要,但防火牆既然有狀態檢測功能,咱們爲何很差好使用它呢?

            --state:state的狀態有四種,指定要匹配包的的狀態,當前有4種狀態可用:INVALID,ESTABLISHED,NEW和RELATED。四種數據包的狀態咱們在前面已經作了詳細的描述本節咱們只進行state的用法描述,以下例所示:

#iptables –A FORWARD –p tcp –m state --state RELATED,ESTABLISHED –j ACCEPT

            本例代表凡是數據包狀態爲「RELATED」、「ESTABLISHED」的tcp包容許經過防火牆。在通常狀況下,基於狀態的策略都是配置在每一條 chain的最前面,由於當包被匹配到之後,就可以直接被處理了,這是一種比較高效的配置方法。

            關鍵字ESTABLISHED比較容易理解,即匹配狀態爲 「已經創建鏈接」的數據包,那麼怎麼理解「RELATED」呢,RELATED表示不屬於已經創建的那條鏈接,但和那條鏈接有關,好比ftp,ftp在創建鏈接的過程當中會首先創建一條ftp-control鏈接用以傳輸指令等,真正傳輸數據的是一條叫作ftp-data的鏈接,而傳輸數據的鏈接是和傳輸控制信號的鏈接相關的,所以「RELATED」是用於相似這些特殊服務的。在正常狀況下,對於每一種協議:TCP、UDP、ICMP均可以單獨的配置狀態策略,但一種比較簡單高效的作法是:

#iptables –A INPUT –p all –m state --state RELATED,ESTABLISHED –j ACCEPT

            multiport:這個匹配選項爲咱們解決了如何在一條策略種匹配那些端口不連續的服務,在通常狀況下,一個公司或企業的安全策略是容許內部網絡使用有限的Internet服務,如收發電子郵件、上網瀏覽網頁、msn聊天等,看看下面的例子:

#iptables –A FORWARD –i eth0 –p tcp –m multiport --dports 25,80,110,443,1863 –j ACCEPT
#iptables –A FORWARD –i eth0 –p udp --dport 53 –j ACCEPT

            僅僅兩條命令就解決了內部用戶上網收發E_mail、瀏覽網頁、使用msn聊天等需求,怎麼樣,就這麼簡單~

相關文章
相關標籤/搜索