1. 程式人生 > >iptables詳解(8):iptables擴展模塊之state擴展

iptables詳解(8):iptables擴展模塊之state擴展

什麽是 80端口 圖片 先來 為我 表示 本機 發送數據 original

當我們通過http的url訪問某個網站的網頁時,客戶端向服務端的80端口發起請求,服務端再通過80端口響應我們的請求,於是,作為客戶端,我們似乎應該理所應當的放行80端口,以便服務端回應我們的報文可以進入客戶端主機,於是,我們在客戶端放行了80端口,同理,當我們通過ssh工具遠程連接到某臺服務器時,客戶端向服務端的22號端口發起請求,服務端再通過22號端口響應我們的請求,於是我們理所應當的放行了所有22號端口,以便遠程主機的響應請求能夠通過防火墻,但是,作為客戶端,如果我們並沒有主動向80端口發起請求,也沒有主動向22號端口發起請求,那麽其他主機通過80端口或者22號端口向我們發送數據時,我們可以接收到嗎?應該是可以的,因為我們為了收到http與ssh的響應報文,已經放行了80端口與22號端口,所以,不管是"響應"我們的報文,還是"主動發送"給我們的報文,應該都是可以通過這兩個端口的,那麽仔細想想,這樣是不是不太安全呢?如果某些與你敵對的人,利用這些端口"主動"連接到你的主機,你肯定會不爽的吧,一般都是我們主動請求80端口,80端口回應我們,但是一般不會出現80端口主動請求我們的情況吧。

你心裏可能會這樣想:我知道哪些主機是安全的,我只要針對這些安全的主機放行對應的端口就行了,其他IP一律拒絕,比如,我知道IP為123的主機是安全的,所以,我對123主機開放了22號端口,以便123主機能夠通過22號端口響應我們的ssh請求,那麽,如果你需要管理的主機越來越多呢?你是不是每次都要為新的主機配置這些規則呢?如果有30臺主機呢?如果有300臺主機呢?80端口就更別提了,難道你每次訪問一個新的網址,都要對這個網址添加信任嗎?這顯然不太合理。

你心裏可能又會想:針對對應的端口,我用--tcp-flags去匹配tcp報文的標誌位,把外來的"第一次握手"的請求拒絕,是不是也可以呢?那麽如果對方使用的是UDP協議或者ICMP協議呢?似乎總是有一些不完美的地方。

那麽我們仔細的思考一下,造成上述問題的"根源"在哪裏,我們為了讓"提供服務方"能夠正常的"響應"我們的請求,於是在主機上開放了對應的端口,開放這些端口的同時,也出現了問題,別人利用這些開放的端口,"主動"的攻擊我們,他們發送過來的報文並不是為了響應我們,而是為了主動攻擊我們,好了,我們似乎找到了問題所在?

問題就是:怎樣判斷這些報文是為了回應我們之前發出的報文,還是主動向我們發送的報文呢?

我們可以通過iptables的state擴展模塊解決上述問題,但是我們需要先了解一些state模塊的相關概念,然後再回過頭來解決上述問題。

從字面上理解,state可以譯為狀態,但是我們也可以用一個高大上的詞去解釋它,state模塊可以讓iptables實現"連接追蹤"機制。

那麽,既然是"連接追蹤",則必然要有"連接"。

咱們就來聊聊什麽是連接吧,一說到連接,你可能會下意識的想到tcp連接,但是,對於state模塊而言的"連接"並不能與tcp的"連接"畫等號,在TCP/IP協議簇中,UDP和ICMP是沒有所謂的連接的,但是對於state模塊來說,tcp報文、udp報文、icmp報文都是有連接狀態的,我們可以這樣認為,對於state模塊而言,只要兩臺機器在"你來我往"的通信,就算建立起了連接,如下圖所示

技術分享圖片技術分享圖片

而報文在這個所謂的鏈接中是什麽狀態的呢?這是我們後面討論的話題。

對於state模塊的連接而言,"連接"其中的報文可以分為5種狀態,報文狀態可以為NEW、ESTABLISHED、RELATED、INVALID、UNTRACKED

那麽上述報文的狀態都代表什麽含義呢?我們先來大概的了解一下概念,然後再結合示例說明。

註意:如下報文狀態都是對於state模塊來說的。

NEW:連接中的第一個包,狀態就是NEW,我們可以理解為新連接的第一個包的狀態為NEW。

ESTABLISHED:我們可以把NEW狀態包後面的包的狀態理解為ESTABLISHED,表示連接已建立。

或許用圖說話更容易被人理解

技術分享圖片技術分享圖片

RELATED:從字面上理解RELATED譯為關系,但是這樣仍然不容易理解,我們舉個例子。

比如FTP服務,FTP服務端會建立兩個進程,一個命令進程,一個數據進程。

命令進程負責服務端與客戶端之間的命令傳輸(我們可以把這個傳輸過程理解成state中所謂的一個"連接",暫稱為"命令連接")。

數據進程負責服務端與客戶端之前的數據傳輸(我們把這個過程贊成為"數據連接")。

但是具體傳輸哪些數據,是由命令去控制的,所以,"數據連接"中的報文與"命令連接"是有"關系"的。

那麽,"數據連接"中的報文可能就是RELATED狀態,因為這些報文與"命令連接"中的報文有關系。

(註:如果想要對ftp進行連接追蹤,需要單獨加載對應的內核模塊nf_conntrack_ftp,如果想要自動加載,可以配置/etc/sysconfig/iptables-config文件)

INVALID:如果一個包沒有辦法被識別,或者這個包沒有任何狀態,那麽這個包的狀態就是INVALID,我們可以主動屏蔽狀態為INVALID的報文。

UNTRACKED:報文的狀態為untracked時,表示報文未被追蹤,當報文的狀態為Untracked時通常表示無法找到相關的連接。

上述5種狀態的詳細解釋可以參考如下文章的"User-land states"章節

http://www.iptables.info/en/connection-state.html

好了,我們已經大致了解了state模塊中所定義的5種狀態,那麽現在,我們回過頭想想剛才的問題。

剛才問題的根源就是:怎樣判斷報文是否是為了回應之前發出的報文。

剛才舉例中的問題即可使用state擴展模塊解決,我們只要放行狀態為ESTABLISHED的報文即可,因為如果報文的狀態為ESTABLISHED,那麽報文肯定是之前發出的報文的回應,如果你還不放心,可以將狀態為RELATED或ESTABLISHED的報文都放行,這樣,就表示只有回應我們的報文能夠通過防火墻,如果是別人主動發送過來的新的報文,則無法通過防火墻,示例如下。

技術分享圖片技術分享圖片

當前主機IP為104,當放行ESTABLISHED與RELATED狀態的包以後,並沒有影響通過本機遠程ssh到IP為77的主機上,那麽此刻,我們在主機77上嘗試訪問104試試。

技術分享圖片技術分享圖片

可以看到,由77主動發送到104的請求被拒絕了。

對於其他端口與IP來說,也是相同的,可以從104主動發送報文,並且能夠收到響應報文,但是其他主機並不能主動向104發起請求。

好了,state模塊就總結到這裏,希望這篇文章能夠對你有所幫助。

iptables詳解(8):iptables擴展模塊之state擴展