在本博客中,從理論到實踐,系統(tǒng)的介紹了iptables,如果你想要從頭開始了解iptables,可以查看iptables文章列表,直達(dá)鏈接如下 當(dāng)我們通過http的url訪問某個網(wǎng)站的網(wǎng)頁時,客戶端向服務(wù)端的80端口發(fā)起請求,服務(wù)端再通過80端口響應(yīng)我們的請求,于是,作為客戶端,我們似乎應(yīng)該理所應(yīng)當(dāng)?shù)姆判?0端口,以便服務(wù)端回應(yīng)我們的報文可以進(jìn)入客戶端主機,于是,我們在客戶端放行了80端口,同理,當(dāng)我們通過ssh工具遠(yuǎn)程連接到某臺服務(wù)器時,客戶端向服務(wù)端的22號端口發(fā)起請求,服務(wù)端再通過22號端口響應(yīng)我們的請求,于是我們理所應(yīng)當(dāng)?shù)姆判辛怂?2號端口,以便遠(yuǎn)程主機的響應(yīng)請求能夠通過防火墻,但是,作為客戶端,如果我們并沒有主動向80端口發(fā)起請求,也沒有主動向22號端口發(fā)起請求,那么其他主機通過80端口或者22號端口向我們發(fā)送數(shù)據(jù)時,我們可以接收到嗎?應(yīng)該是可以的,因為我們?yōu)榱耸盏絟ttp與ssh的響應(yīng)報文,已經(jīng)放行了80端口與22號端口,所以,不管是"響應(yīng)"我們的報文,還是"主動發(fā)送"給我們的報文,應(yīng)該都是可以通過這兩個端口的,那么仔細(xì)想想,這樣是不是不太安全呢?如果某些與你敵對的人,利用這些端口"主動"連接到你的主機,你肯定會不爽的吧,一般都是我們主動請求80端口,80端口回應(yīng)我們,但是一般不會出現(xiàn)80端口主動請求我們的情況吧。 你心里可能會這樣想:我知道哪些主機是安全的,我只要針對這些安全的主機放行對應(yīng)的端口就行了,其他IP一律拒絕,比如,我知道IP為123的主機是安全的,所以,我對123主機開放了22號端口,以便123主機能夠通過22號端口響應(yīng)我們的ssh請求,那么,如果你需要管理的主機越來越多呢?你是不是每次都要為新的主機配置這些規(guī)則呢?如果有30臺主機呢?如果有300臺主機呢?80端口就更別提了,難道你每次訪問一個新的網(wǎng)址,都要對這個網(wǎng)址添加信任嗎?這顯然不太合理。 你心里可能又會想:針對對應(yīng)的端口,我用--tcp-flags去匹配tcp報文的標(biāo)志位,把外來的"第一次握手"的請求拒絕,是不是也可以呢?那么如果對方使用的是UDP協(xié)議或者ICMP協(xié)議呢?似乎總是有一些不完美的地方。 那么我們仔細(xì)的思考一下,造成上述問題的"根源"在哪里,我們?yōu)榱俗?quot;提供服務(wù)方"能夠正常的"響應(yīng)"我們的請求,于是在主機上開放了對應(yīng)的端口,開放這些端口的同時,也出現(xiàn)了問題,別人利用這些開放的端口,"主動"的攻擊我們,他們發(fā)送過來的報文并不是為了響應(yīng)我們,而是為了主動攻擊我們,好了,我們似乎找到了問題所在? 問題就是:怎樣判斷這些報文是為了回應(yīng)我們之前發(fā)出的報文,還是主動向我們發(fā)送的報文呢? 我們可以通過iptables的state擴(kuò)展模塊解決上述問題,但是我們需要先了解一些state模塊的相關(guān)概念,然后再回過頭來解決上述問題。 從字面上理解,state可以譯為狀態(tài),但是我們也可以用一個高大上的詞去解釋它,state模塊可以讓iptables實現(xiàn)"連接追蹤"機制。 那么,既然是"連接追蹤",則必然要有"連接"。 咱們就來聊聊什么是連接吧,一說到連接,你可能會下意識的想到tcp連接,但是,對于state模塊而言的"連接"并不能與tcp的"連接"畫等號,在TCP/IP協(xié)議簇中,UDP和ICMP是沒有所謂的連接的,但是對于state模塊來說,tcp報文、udp報文、icmp報文都是有連接狀態(tài)的,我們可以這樣認(rèn)為,對于state模塊而言,只要兩臺機器在"你來我往"的通信,就算建立起了連接,如下圖所示 而報文在這個所謂的鏈接中是什么狀態(tài)的呢?這是我們后面討論的話題。 對于state模塊的連接而言,"連接"其中的報文可以分為5種狀態(tài),報文狀態(tài)可以為NEW、ESTABLISHED、RELATED、INVALID、UNTRACKED 那么上述報文的狀態(tài)都代表什么含義呢?我們先來大概的了解一下概念,然后再結(jié)合示例說明。 注意:如下報文狀態(tài)都是對于state模塊來說的。 NEW:連接中的第一個包,狀態(tài)就是NEW,我們可以理解為新連接的第一個包的狀態(tài)為NEW。 ESTABLISHED:我們可以把NEW狀態(tài)包后面的包的狀態(tài)理解為ESTABLISHED,表示連接已建立。 或許用圖說話更容易被人理解 RELATED:從字面上理解RELATED譯為關(guān)系,但是這樣仍然不容易理解,我們舉個例子。 比如FTP服務(wù),F(xiàn)TP服務(wù)端會建立兩個進(jìn)程,一個命令進(jìn)程,一個數(shù)據(jù)進(jìn)程。 命令進(jìn)程負(fù)責(zé)服務(wù)端與客戶端之間的命令傳輸(我們可以把這個傳輸過程理解成state中所謂的一個"連接",暫稱為"命令連接")。 數(shù)據(jù)進(jìn)程負(fù)責(zé)服務(wù)端與客戶端之間的數(shù)據(jù)傳輸 ( 我們把這個過程暫稱為"數(shù)據(jù)連接" )。 但是具體傳輸哪些數(shù)據(jù),是由命令去控制的,所以,"數(shù)據(jù)連接"中的報文與"命令連接"是有"關(guān)系"的。 那么,"數(shù)據(jù)連接"中的報文可能就是RELATED狀態(tài),因為這些報文與"命令連接"中的報文有關(guān)系。 (注:如果想要對ftp進(jìn)行連接追蹤,需要單獨加載對應(yīng)的內(nèi)核模塊nf_conntrack_ftp,如果想要自動加載,可以配置/etc/sysconfig/iptables-config文件) INVALID:如果一個包沒有辦法被識別,或者這個包沒有任何狀態(tài),那么這個包的狀態(tài)就是INVALID,我們可以主動屏蔽狀態(tài)為INVALID的報文。 UNTRACKED:報文的狀態(tài)為untracked時,表示報文未被追蹤,當(dāng)報文的狀態(tài)為Untracked時通常表示無法找到相關(guān)的連接。 上述5種狀態(tài)的詳細(xì)解釋可以參考如下文章的"User-land states"章節(jié) http://www./en/connection-state.html 好了,我們已經(jīng)大致了解了state模塊中所定義的5種狀態(tài),那么現(xiàn)在,我們回過頭想想剛才的問題。 剛才問題的根源就是:怎樣判斷報文是否是為了回應(yīng)之前發(fā)出的報文。 剛才舉例中的問題即可使用state擴(kuò)展模塊解決,我們只要放行狀態(tài)為ESTABLISHED的報文即可,因為如果報文的狀態(tài)為ESTABLISHED,那么報文肯定是之前發(fā)出的報文的回應(yīng),如果你還不放心,可以將狀態(tài)為RELATED或ESTABLISHED的報文都放行,這樣,就表示只有回應(yīng)我們的報文能夠通過防火墻,如果是別人主動發(fā)送過來的新的報文,則無法通過防火墻,示例如下。 當(dāng)前主機IP為104,當(dāng)放行ESTABLISHED與RELATED狀態(tài)的包以后,并沒有影響通過本機遠(yuǎn)程ssh到IP為77的主機上,但是無法從104上使用22端口主動連接到77上。 對于其他端口與IP來說,也是相同的,可以從104主動發(fā)送報文,并且能夠收到響應(yīng)報文,但是其他主機并不能主動向104發(fā)起請求。 好了,state模塊就總結(jié)到這里,希望這篇文章能夠?qū)δ阌兴鶐椭?/p> |
|