歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux技術 >> 文科生也能看懂的Linux iptables入門教程

文科生也能看懂的Linux iptables入門教程

日期:2017/3/1 17:53:19   编辑:Linux技術

對於斗膽開始玩vps的文科生來講,iptables簡直是地獄中的地獄。有幾家vps供應商系統默認是帶著些iptables規則的,以前我一向是難言之隱,一清了之。

我很早就知道這東西重要,但看著太難了,後來看到log裡越來越多的攻擊記錄,心想這東西得必須學了,說不定哪天哪個龜孫子就攻進來了。網上及電子書中的教程一般對於文科生來講比較難看懂,有的還畫著圖,號稱a picture can tell a thousand words. 但有圖也看不懂,你說畫個桌子,我知道英語是table、日語稱雞雞。但這個根本不存在的table,你畫出來,對於連看懂火車時刻表都表示有困難的我,我會更糊塗的。

說閒話少說的時候,實際上是說了很多閒話….咬咬牙開始吧,我還是要不怕困難,寫一個連文科生都能看懂的iptables心得!

如其名稱所示,iptables,就是裡面有好幾個table,大約有過濾桌、nat桌、mangle桌啥的。後兩個你先別管,等我搞明白了再來教你,第一個桌子從名稱上一看就明白了,過濾數據用的,它也正是我們用來防止攻擊用的——把壞人過濾掉,不讓他進來!那我們就講這個過濾桌吧。

這個桌子上放有一條一條的chain,就是鏈子。每個鏈子由尺子(rules)組成…嚴肅點,我不開玩笑了,這麼說吧,table(表)由chain(鏈)組成,Chain又有規則組成(rules)。

既然我們只講 filter table(過濾表),那麼table這個概念就跟我們無關了,重點要理解“鏈”和組成“鏈”的“rule (規則)”。

鏈(chain)與規則 (rules)

filter table裡面有三個默認的鏈,INPUT,OUTPUT 和 FORWARD。FORWARD呢對於做站基本用不上,我們就講INPUT 和 OUTPUT。因為是別人要攻擊我們,對於我們的服務器來講,攻擊是要進來的,即INPUT,诶?那麼說把 INPUT這個鏈搞明白,就可以防守了?差不多吧。那我們就只講 INPUT好了,越簡單越好,關鍵是把概念理清楚,別的細節,都可以查到的的親。另外,INPUT, OUTPUT, FORWARD都是由規則組成的鏈,INPUT搞懂了,其他的也就不難了。

平常我們看到iptables,就是一條條的規則,例如:


復制代碼代碼如下:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

看到INPUT這個詞了吧?這說明這條規則屬於INPUT這個鏈的,tcp是協議,網站都是用tcp的, –dport 80,就是80這個端口,也就是別人打開你的網站的時候需要與你的服務器的80端口連起來,就像一條打印機線把電腦的打印機口與打印機連起來一樣,不過網絡上端口是虛擬的,但實際工作的時候是一回事,就是通信。對於INPUT(發進來)的數據包,80是目標端口,即destination port, 簡稱 dport。

因為你的服務器上放了你的網站,你需要允許別人向80端口發連接請求,ACCEPT,即接受請求和連接。現在你明白了吧?有了這句,別人就可以連接你的服務器,打開上面的網頁了。

前面那個“-A”的意思append,與後面的INPUT連用的,就是把這條規則加到INPUT這個鏈的最後面。當然現我們INPUT這個鏈上啥都沒有,加到最後面,也就是第一條了。

命令行的規則你大概明白了吧,“-”符號,後面直接跟的是參數名,參數名後跟空格,空格後跟這個參數的值(姑且這麼理解吧)。例如 -p tcp ,這裡的‘-p’是不能隨便寫的,是iptables程序定義的,你寫個“-p”,程序就知道後面跟的是協議名稱。你寫個“-A”,iptables程序就知道後面跟的是鏈的名稱。那麼“–dport”裡的兩個減號“–”是啥意思呢?它的功能跟一個減號是一樣的,都表示後面是參數名,不過兩個減號後面跟的參數名的全稱,一個減號跟的是簡稱,全稱容易看懂,減稱寫起來省勁。例如上面這句規則也可以寫成:

復制代碼代碼如下:
iptables -append INPUT --proto tcp --dport 80 --jump ACCEPT

當然,愛裝逼的理科生一般是不會寫全稱的,大都用一個減號,一個字母的簡稱。
親愛的windows用戶,注意這裡的參數名和參數值都是大小寫敏感的,把“-p”寫成“-P”,程序是不工作的。另外英語很好的你可以注意到了,即使是加了兩個減號的“全稱”,也不全,proto明明不對,該是protocol才對。你知道他們理科生語文不好,原諒他們吧。

光有這條還不夠,因為你的vps上還有別的服務,例如你上傳文件需要ftp或sftp,進入後台需要ssh,ftp的默認端口是21,ssh是22,我們把它們也加上。


復制代碼代碼如下:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

好了,你准備就開放這麼多服務,最後在加一句


復制代碼代碼如下:
iptables -A INPUT -j DROP

它的意思是拒絕所有連接…這怎麼行?不是說要允許80,21,和22嗎?這是因為INPUT是個鏈子,有頭有尾,按順序來的。如果有人連接你的80口,第一句規則說ACCEPT,進來吧。那麼他發來的一梭子彈彈就不再經過後面的規則了,當然也就不會被放在最後面的DROP這句拒絕了。

現在我們的全部規則是:

復制代碼代碼如下:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -j DROP

翻譯成文科生的語言就是發到80(嘴巴),21(菊花),22(貓貓)三個口的數據將接受,想往別的地方塞數據,一律拒絕。復習一下開始說的,這些東東的意思是在INPUT這個鏈子上有四條規則,規則是按順序一個一個來的,發來的數據被匹配後,就跳出鏈子,後面的規則就不再執行了。如果你把iptables -A INPUT -j DROP這條放在鏈頭,你的vps就變成了石女,唯有通過服務商的面板重啟了!

REJECT 和 DROP

剛才-j 後面的拒絕操作是DROP,正確的英語譯文該是”REJECT”才對。是的,寫成”-j REJECT”也是可以的。不同之處是REJECT比較客氣,等於告訴想搞你的人“對不起,人家這兩天不方便。”而DROP就是一聲不坑地拒絕。對於入侵者,不用那麼客氣,用DROP好了。因為如果你回應了,等於告訴想搞你的人你是在線的,只是拒絕了,反而會引起他繼續努力的斗志。

狀態 (state)匹配

如果你喜顛顛地拿著上面幾條去試驗了,估計你的vps上的一些網站可能就竿屁了,iptables這個妹妹很難對付的。要想讓你的服務器正常工作,還需要添加這一句在DROP那一句之前。


復制代碼代碼如下:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

“-m”是“匹配”的意思,-m state的意思是匹配數據包狀態,用戶發來的數據包分別帶有不同的狀態,即 NEW, ESTABLISHED, 和 RELATED。NEW 就是開頭搭讪,ESTABLISHED,就是搭讪完了之後後續的數據包,RELATED就是與已經存在的連接相關的數據包。總之這句話的意思是,接受已經建立了連接的數據包,即搭讪之後的數據包。現在我們的INPUT鏈是這個樣子的:

復制代碼代碼如下:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -j DROP

意思是外面接受發往本機80,21,22的tcp數據包,還接受發往任何端口的已建立(established)和相關(related)的數據包(第四句),剩下的INPUT數據包一律拋棄。

為毛要允許狀態ESTABLISHED 和 RELATED的入站數據呢?因為你的服務器同時也是台電腦,還要從別的服務器下載東西。下載時,你的服務器先向別的服務器發出連接請求(new),別的服務器允許你連接,連接建立(ESTABLISHED)之後,就需要接受別的服務器發來的數據,對於你的服務器來講屬於INPUT。也就是說,如果沒有iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT這句,wget curl啥的就都不工作了。有了這句,加上前三句,即允許別的電腦連接(new)你的80,21和22端口,同時允許別的服務器在你的服務器先向它發請求的條件下向你發送數據。另外這些狀態都是基於tcp協議來講的(謝謝BOYPT)。

-A(–append)和-I (–insert)

剛才說了,-A INPUT的意思是把一條規則加在現有INPUT這個鏈子的最後面,那麼寫成-I INPUT,就是把一條規則強行插入到最前面。如果你比較變態,剛才的INPUT鏈倒著寫也是可以的:

復制代碼代碼如下:
iptables -I INPUT -j DROP
iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -I INPUT -p tcp --dport 22 -j ACCEPT
iptables -I INPUT -p tcp --dport 21 -j ACCEPT
iptables -I INPUT -p tcp --dport 80 -j ACCEPT

即後面一條總會插到現有INPUT鏈的最前面,最終形成的INPUT鏈跟前面是一樣的。
不過,不要試!因為你通常是遠程操作你的vps的,你在命令行輸入第一句,立馬掉線!後面就全輸不進去了!
–insert也是有用的,例如前面這個INPUT鏈已經起了作用,你想在不清空現有INPUT鏈的基礎上再開放一個端口,例如443。那麼就必須寫成

復制代碼代碼如下:
iptables -I INPUT -p tcp --dport 443 -j ACCEPT

如果你寫成 -A,那麼這條規則就被跟在DROP那句後面,發到443的數據在來到新加的這句之前,就被干掉了。

如果你不想加到最前面,也可以在INPUT後面寫個數字,表示添加的位置,如果把一條規則看成一行,也就是指定所謂的行號了。把上面添加443端口的規則寫成:

復制代碼代碼如下:
iptables -I INPUT 3 -p tcp --dport 443 -j ACCEPT

那麼就把它放在了第三條規則(即第三行)的位置了。在命令行裡輸入 iptables -nvx -L INPUT (查看現在生效的INPUT鏈),你會發現新增加的這條規則在21端口那句的後面。

把上面的規則保存到文件裡,運行一下,你的服務器就安全多了。


復制代碼代碼如下:
iptables --flush
iptables --delete-chain
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -j DROP

關於iptables的其他內容,如記錄日志、屏蔽IP、建立自定義鏈……,日後再說吧!無論如何,搞懂今天講的概念是最重要的,其他的細節都可以查到的,總是粘貼別人寫好的規則,但一直啥也不懂,不是我們的文科生應該做的。

思考題:應用以上規則之後,服務器運行正常,但你無法在家ping你的服務器了!這是什麼呢?

Copyright © Linux教程網 All Rights Reserved