1. 程式人生 > >iptables防火牆簡介,原理,規則編寫,常見案例

iptables防火牆簡介,原理,規則編寫,常見案例

#### 防火牆簡述 > 防火牆(firewall)一詞本是建築用於,本意是為了保護建築物不受火災侵害的。被借鑑到了在網路通訊領域中,表示保護區域網或主機不受網路攻擊的侵害。 `防火牆: 工作在主機或者網路邊緣,對於進出的資料報文按照事先定義好的規則進行檢查,監控,一旦符合標準,我們就按照事先定義好的規則處理動作的一套機制元件叫做(網路)(主機)防火牆` ![](https://img2020.cnblogs.com/blog/1871335/202011/1871335-20201108181148260-301923920.png) > 目前市面上比較常見的有3,4層的防火牆,叫做網路層防火牆,還有七層的防火牆,其實是代理層的閘道器. > > 對於TCP/IP的七層模型來講,我們知道第三層是網路層,三層的防火牆會在這層對源地址和目標地址進行檢測,但是對於七層的防火牆,不管你是源埠或者目標埠,源地址或者目標地址是什麼,都將對你所有的東西進行檢查. 所以對於設計原理來講,七層防火牆更加安全, 但是這卻帶來了效率更低, 所以市面上通常的防火牆方案,都是兩者結合的. 而又由於我們都需要從防火牆所控制的這個口來訪問,所以防火牆的工作效率就成了使用者能訪問資料多少的一個最重要的控制,配置的不好甚至可能成為流量的瓶頸. > > 根據防範的方式和側重點的不通分為很多種型別, 但總體來講可分為包過濾防火牆和代理伺服器兩種型別. #### 防火牆分類 ##### 主機防火牆 `工作在某個主機邊緣,主要對進出本主機` `報文的分層識別,都是在系統核心級別實現的,故防火牆也工作在單臺主機核心空間中[TCP/IP協議棧上],其只能作用於單臺主機` ##### 網路防火牆 `網路中的防火牆裝置,可分為三種:代理防火牆、包過濾防火牆、狀態監測防火牆。` `代理防火牆` > 代理防火牆是代理內網主機上網的裝置,可以是路由器,也可以是一臺主機兩塊網絡卡,一連內網、一連公網,以代替內網主機訪問公網資源,又被稱為nat(網路地址轉換伺服器、或nat堡壘伺服器); `工作原理` > 在應用層實現防火牆功能, 提供部分和傳輸有關的狀態,能完全提供與應用相關的狀態和部分傳輸的資訊,他還能處理和管理資訊. **包過濾防火牆** > 包過濾防火牆是檢測所通過資料包,可監測到資料包中源ip、目的ip、源埠、目的埠、標記位等資訊,並根據事先制定的通訊規則決定資料包是否轉發; `工作原理` > 在網路層對資料包進行選擇過濾,採用訪問控制列表(Access control table -ACL)檢查資料流的源地址,目的地址,源和目的埠,IP等資訊. > > netfilter/iptables(簡稱為iptables)組成Linux平臺下的包過濾防火牆,與大多數Linux軟體一樣, 這個包過濾防火牆是免費的, 他可以替代昂貴的商業防火牆解決方案,完成封包過濾,封包重定向和網路地址轉換(NAT)等功能. ![](https://img2020.cnblogs.com/blog/1871335/202011/1871335-20201108181156609-409643601.png) `狀態監測防火牆` > 狀態監測防火牆除了可以監測資料包中的內容外,還可以跟蹤每個客戶的每次通訊,當有攻擊資料在開始時偽裝成正常訪問,之後突然開始做攻擊時,會被狀態監測防火牆監測到並加以遮蔽。 `在Linux系統中,防火牆工具使用的是iptables,可實現代理防火牆、包(資料報文)過濾防火牆,nat,mangle等規則的功能,而狀態監測防火牆一般是企業購買專用的防火牆裝置完成的。` ##### 軟體防火牆 `軟體邏輯實現` `軟體防火牆由工作在通用計算機[即x86系列cpu]上的系統核心通過呼叫底層通用cpu指令集實現;` ##### 硬體防火牆 `硬體和軟體邏輯組合實現,為某種特殊功能設計和實現,靈活性差` `硬體防火牆使用專業的CPU,其在CPU的硬體級別就能完成對於報文的拆封操作;其只能實現防火牆資料流控制的相關功能;` `效能很好[因為其在CPU的指令級別就已經實現了相對複雜的功能,其不用在邏輯層進行復雜的指令組合即可完成對應功能` ##### 資料流向 ```go /* 資料包--> 網絡卡驅動 --> 核心記憶體空間--> TCP/IP協議棧分析目標IP -->若是本機ip,則再檢視埠並交由相關程式 --> 若不是本機ip,當開啟路由轉發功能後, 核心將會檢視本機路由表,將資料包交由對應網絡卡介面,作為下一跳; 若沒有路由條目,則將此報文交由預設閘道器,由預設閘道器將其轉發到相關主機; */ ``` ##### Linux核心通訊邏輯 > 通訊是程序之間進行的, 客戶端和服務端的程式通過建立tcp連線, 通過套接字進行資料傳輸. > > 將所有埠開放給所有內部主機,以保證通訊的正常進行, 而防火牆為了保證安全, 在所有埠之外進行了限制, 只有某些規定允許的端口才能開放給外部主機進行訪問使用 ​ **Linux防火牆的發展:** ```go /* 1.0時代 --> ipfirewall 2.0時代 --> ipchains 3.0時代 --> iptables 4.0時代 --> nftables */ ``` #### Iptables工作原理(四表五鏈) ##### 五鏈 > 五個鉤子函式(hook functionns),也叫五個規則(rules)鏈(chains) (資料包傳播的路徑) ```go /* prerouting 路由前 input 資料包流入口 forward 轉發網絡卡 output 資料包出口 postrouting 路由後 */ ``` > 這是NetFilter規定的五個規則鏈,任何一個數據包,只要經過本機,必將經過五個鏈中的其中一個鏈 `防火牆策略一般分為兩種, 一種叫"通"策略,一種叫"堵"策略:` ```go /* 通策略, 預設門是關著的, 必須要定義誰能進. 堵策略,大門是開啟的,但是你必須有身份你認證,否則不能進去. */ ``` ##### 表的概念 > 我們再想想另外一個問題,我們對每個"鏈"上都放置了一串規則,但是這些規則有些很相似,比如,A類規則都是對IP或者埠的過濾,B類規則是修改報文,那麼這個時候,我們是不是能把實現相同功能的規則放在一起呢,必須能的。 > > 我們把具有相同功能的規則的集合叫做"表",所以說,不同功能的規則,我們可以放置在不同的表中進行管理,而iptables已經為我們定義了4種表,每種表對應了不同的功能,而我們定義的規則也都逃脫不了這4種功能的範圍,所以,學習iptables之前,我們必須先搞明白每種表 的作用. `iptables為我們提供瞭如下規則的分類,或者說,iptables為我們提供瞭如下"表"` ```go /* filter表:負責過濾功能,防火牆;核心模組:iptables_filter nat表:network address translation,網路地址轉換功能;核心模組:iptable_nat mangle表:拆解報文,做出修改,並重新封裝 的功能;iptable_mangle raw表:關閉nat表上啟用的連線追蹤機制;iptable_raw 也就是說,我們自定義的所有規則,都是這四種分類中的規則,或者說,所有規則都存在於這4張"表"中。 */ ``` `Filter` > filter實現包過濾,定義允許或者不允許的[ 只能做在3個鏈上: INPUT表(進入的包), FORWORD(轉發的包), OUTPUT(處理本地生成的包), filter表只能對包進行接收和丟棄的操作. `NAT` > nat網路地址轉換(只能做在3個鏈上: Prerouting(修改即將到來的資料包), output(修改在路由之前本地生成的資料包), Postrouting(修改即將出去的資料包) `Mangle` > mangle包重構(修改), 修改報文原資料就是來修改TTL的, 能夠實現將資料包的元資料拆開, 在裡面做標記/修改內容的. 而防火牆標記, 其實就是靠mangle來實現的. 五個鏈都可以做. `raw` > 資料跟蹤處理 ![](https://img2020.cnblogs.com/blog/1871335/202011/1871335-20201108181205634-1427181161.png) ##### Iptables傳輸資料包過程 `1. 當一個數據包進入網絡卡時, 他首先進入prerouting鏈, 核心根據資料包目的IP判斷是否傳送出去.` `2. 如果資料包進入本機, 他就會沿著圖向下移動, 到達input鏈, 資料包到了input鏈後,任何程序都會收到他,本機上執行的程式可以傳送資料包, 這些資料包會經過output鏈, 然後到達postrouting鏈輸出` `3. 如果資料包要轉發出去,且核心允許轉發,資料包就會如圖所示向右移動,經過Forward鏈, 然後到達Postrouting鏈輸出` ![](https://img2020.cnblogs.com/blog/1871335/202011/1871335-20201108181214869-2126768825.png) ![](https://img2020.cnblogs.com/blog/1871335/202011/1871335-20201108181224561-806190225.png) > iptables/netfilter(這款軟體)是工作在使用者空間的,他可以讓規則進行生效的,本身不是一種服務, 而且規則是立即生效的, 而我們iptables現在被做成了一個服務, 可以進行啟動,停止的, 啟動,則將規則直接生效, 停止,則將規則撤銷. `自定義鏈` `iptables還支援自己自定義鏈, 但是自己自定義的鏈, 必須是跟某種特定的鏈關聯起來的, 在一個關卡設定, 指定當有資料的時候專門去找某個特定的鏈來處理, 當那個鏈處理完之後, 再返回,接著在特定的鏈中繼續檢查.只有在被呼叫時才能發揮作用, 而且如果沒有自定義鏈中的` `注意: 規則的次序非常關鍵,檢查規則是按照從上往下的方式進行檢查的` ```go /* 使用者可以刪除自定義的空鏈 預設鏈無法刪除 每個規則都有兩個內建的計數器 被匹配的報文個數 被匹配的報文體積大小之和 */ ``` ##### 錶鏈關係 > 但是我們需要注意的是,某些"鏈"中註定不會包含"某類規則",就像某些"關卡"天生就不具備某些功能一樣,比如,A"關卡"只負責打擊陸地敵人,沒有防空能力,B"關卡"只負責打擊空中敵人,沒有防禦步兵的能力,C"關卡"可能比較NB,既能防空,也能防禦陸地敵人,D"關卡"最屌,海陸空都能防。 > > 那讓我們來看看,每個"關卡"都有哪些能力,或者說,讓我們看看每個"鏈"上的規則都存在於哪些"表"中。 > > 我們還是以圖為例,先看看prerouting"鏈"上的規則都存在於哪些表中。 ![](https://img2020.cnblogs.com/blog/1871335/202011/1871335-20201108181232672-444731726.png) > 這幅圖是什麼意思呢?它的意思是說,prerouting"鏈"只擁有nat表、raw表和mangle表所對應的功能,所以,prerouting中的規則只能存放於nat表、raw表和mangle表中。 `我們總結一下,每個關卡都擁有什麼功能` ```go /* PREROUTING 的規則可以存在於:raw表,mangle表,nat表。 INPUT 的規則可以存在於:mangle表,filter表,(centos7中還有nat表,centos6中沒有)。 FORWARD 的規則可以存在於:mangle表,filter表。 OUTPUT 的規則可以存在於:raw表mangle表,nat表,filter表。 POSTROUTING 的規則可以存在於:mangle表,nat表。 */ ``` > 但是,我們在實際的使用過程中,往往是通過"表"作為操作入口,對規則進行定義的,之所以按照上述過程介紹iptables,是因為從"關卡"的角度更容易從入門的角度理解,但是為了以便在實際使用的時候,更加順暢的理解它們,此處我們還要將各"表"與"鏈"的關係羅列出來, `表(功能) <--> 鏈(鉤子)` ```go /* raw 表中的規則可以被那些鏈使用: prerouting,output mangle表中的規則可以被那些鏈使用: prerouting, input, forward,output, postrouting nat表中的規則可以被那些鏈使用: prerouting, output, postrouting (centos7中還有input,centos6中沒有) filter表中的規則可以被那些鏈使用: input,forward,output */ ``` > 其實我們還需要注意一點,因為資料包經過一個"鏈"的時候,會將當前鏈的所有規則都匹配一遍,但是匹配時總歸要有順序,我們應該一條一條的去匹配,而且我們說過,相同功能型別的規則會匯聚在一張"表"中,那麼,哪些"表"中的規則會放在"鏈"的最前面執行呢,這時候就需要有一個優先順序的問題 `iptables為我們定義了四張表, 當他們處於同一張鏈時, 執行的優先順序如下` ```go /* prerouting鏈中的規則存放於三張表中, 而這三張表的規則執行優先順序如下: raw --> mangle --> nat 優先順序次序(由高而低) raw --> managle --> nat --> filter */ ``` > 但是我們前面說過,某些鏈天生就不能使用某些表中的規則,所以,4張表中的規則處於同一條鏈的目前只有output鏈,它就是傳說中海陸空都能防守的關卡。 > > > > 為了更方便的管理,我們還可以在某個表裡面建立自定義鏈,將針對某個應用程式所設定的規則放置在這個自定義鏈中,但是自定義連結不能直接使用,只能被某個預設的鏈當做動作去呼叫才能起作用,我們可以這樣想象,自定義鏈就是一段比較"短"的鏈子,這條"短"鏈子上的規則都是針對某個應用程式制定的,但是這條短的鏈子並不能直接使用,而是需要"焊接"在iptables預設定義鏈子上,才能被IPtables使用,這就是為什麼預設定義的"鏈"需要把"自定義鏈"當做"動作"去引用的原因。這是後話,後面再聊,在實際使用時我們即可更加的明白。 `結合上述所有的描述,我們可以將資料包通過防火牆的流程總結為下:` 我們在寫Iptables規則的時候,要時刻牢記這張路由次序,靈活配置規則。 我們將經常用到的對應關係重新寫在此處,方便對應圖例檢視。 鏈的規則存放於哪些表中(從鏈到表的對應關係): ```go /* PREROUTING 的規則可以存在於:raw表,mangle表,nat表。 INPUT 的規則可以存在於:mangle表,filter表,(centos7中還有nat表,centos6中沒有)。 FORWARD 的規則可以存在於:mangle表,filter表。 OUTPUT 的規則可以存在於:raw表mangle表,nat表,filter表。 POSTROUTING 的規則可以存在於:mangle表,nat表。 表中的規則可以被哪些鏈使用(從表到鏈的對應關係): raw 表中的規則可以被哪些鏈使用:PREROUTING,OUTPUT mangle 表中的規則可以被哪些鏈使用:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING nat 表中的規則可以被哪些鏈使用:PREROUTING,OUTPUT,POSTROUTING(centos7中還有INPUT,centos6中沒有) filter 表中的規則可以被哪些鏈使用:INPUT,FORWARD,OUTPUT */ ``` #### iptables規則寫法 ##### 規則的概念 `規則` `根據指定的匹配條件來嘗試匹配每個流經此處的報文,一旦匹配成功,則由規則後面指定的處理動作進行處理;` > 那麼我們來通俗的解釋一下什麼是iptables的規則,之前打過一個比方,每條"鏈"都是一個"關卡",每個通過這個"關卡"的報文都要匹配這個關卡上的規則,如果匹配,則對報文進行對應的處理,比如說,你我二人此刻就好像兩個"報文",你我二人此刻都要入關,可是城主有命,只有器宇軒昂的人才能入關,不符合此條件的人不能入關,於是守關將士按照城主制定的"規則",開始打量你我二人,最終,你順利入關了,而我已被拒之門外,因為你符合"器宇軒昂"的標準,所以把你"放行"了,而我不符合標準,所以沒有被放行,其實,"器宇軒昂"就是一種"匹配條件","放行"就是一種"動作","匹配條件"與"動作"組成了規則。 `規則由匹配條件和處理動作組成` **匹配條件** ```go /* 分為基本匹配條件與擴充套件匹配條件 基本匹配條件: 源地址Source IP, 目標地址DestinationIP. 擴充套件匹配條件: 分為 1.隱含擴充套件: 不用特別指明那個模組進行的擴充套件,因為此時用-p {tcp|udp|icmp} 除去上面條件可以用於匹配,還有其他條件可以用於匹配,這些條件泛稱為擴充套件條件. 這些擴充套件條件其實是netfilter中的一部分, 只是以模組的形式存在,如果想使用這些條件,則需要依賴對應的擴充套件模組. 源埠Source Port,目標埠Destination Port 2.顯式擴充套件: 必須指明由那個模組進行的擴充套件,在iptables中使用-m選項既可完成功能. */ ``` **處理動作** > 處理動作在iptables中被稱為target(這樣說並不準確,我們暫且這樣稱呼),動作也可以分為基本動作和擴充套件動作. ```go /* ACCEPT:允許資料包通過。 DROP:直接丟棄資料包,不給任何迴應資訊,這時候客戶端會感覺自己的請求泥牛入海了,過了超時時間才會有反應。 REJECT:拒絕資料包通過,必要時會給資料傳送端一個響應的資訊,客戶端剛請求就會收到拒絕的資訊。 SNAT:源地址轉換,解決內網使用者用同一個公網地址上網的問題。 MASQUERADE:是SNAT的一種特殊形式,適用於動態的、臨時會變的ip上。 DNAT:目標地址轉換。 REDIRECT:在本機做埠對映。 LOG:在/var/log/messages檔案中記錄日誌資訊,然後將資料包傳遞給下一條規則,也就是說除了記錄以外不對資料包做任何其他操作,仍然讓下一條規則去匹配。 */ ``` ![](https://img2020.cnblogs.com/blog/1871335/202011/1871335-20201108181245348-1810057712.png) ##### 語法構成 ```go /* iptables [-t 表名] 選項 [鏈名] [條件] [-j 控制型別] 注意事項 1. 不指定表名時, 預設指filter表. 2. 不指定鏈名時, 預設指表內的所有鏈. 3. 除非設定鏈的預設策略, 否則必須指定匹配條件. 4. 選項,鏈名,控制型別使用大寫字母,其餘均小寫 */ ``` ##### 管理規則 ```go /* 新增新的規則: -A: 在鏈的末尾追加一條規則 -I: 在鏈的開頭(或指定序號)插入一條規則 -s: --src: 指定源地址 -d: --dst: 指定目標地址 -p: {tcp|udp|icmp}: 指定協議 -i(INTERFACE): 指定資料報文流入的介面PREROUINT. -o(INTERFACE): 指定資料報文流出的介面. iptables -t filter -A INPUT -p tcp -j ACCEPT iptables -I INPUT -p udp -j ACCEPT iptables -I INPUT 2 -p icmp -j ACCEPT 檢視規則 iptables -L INPUT --line-numbers -L: 列出所有規則條目 -n: 以數字形式顯示主機地址,埠等資訊 -v: 以更詳細的方式顯示規則資訊 --line-numbers: 檢視規則時,顯示規則的序號 替換規則 -R CHAIN [num]: 替換指定的規則 刪除,清空規則 -D: 刪除鏈內指定序號(或內容)的一條規則. -F: 清空所有的規則鏈 iptables -D INPUT 3 iptables -n -L INPUT 管理鏈 -P CHAIN: 設定指定鏈預設策略 -N: 自定義一個新的空鏈 -X: 刪除一個自定義空鏈 -E: 置零指定鏈中所有規則的計數器 */ ``` ##### 控制型別 ```go /* 1. ACCEPT: 允許通過 2. DROP: 直接丟棄,不給出任何迴應 3. REJECT: 拒絕通過,必要時會給出提示. 4. LOG: 記錄日誌資訊, 然後傳給下一條規則繼續匹配 5. SNAT: 修改資料包源地址 6. REDIRECT: 重定向 */ ``` #### 常見案例 ##### 檢視規則 ##### iptables禁止某IP訪問 > 在CentOS下封停IP,有封殺網段和封殺單個IP兩種形式。一般來說,現在的攻擊者不會使用一個網段的IP來攻擊(太招搖了),IP一般都是雜湊的。於是下面就詳細說明一下封殺單個IP的命令,和解封單個IP的命令。 > > > > 在CentOS下,使用ipteables來維護IP規則表。要封停或者是解封IP,其實就是在IP規則表中對入站部分的規則進行新增操作。 `要封停一個IP,使用下面這條命令:` ```markup iptables -I INPUT -s ***.***.***.*** -j DROP ``` `要解封一個IP,使用下面這條命令` ```markup iptables -D INPUT -s ***.***.***.*** -j DROP ``` > 引數-I是表示Insert(新增),-D表示Delete(刪除)。後面跟的是規則,INPUT表示入站,***.***.***.***表示要封停的IP,DROP表示放棄連線。 `此外,還可以使用下面的命令來檢視當前的IP規則表:` ```markup iptables --list ``` `比如現在要將123.44.55.66這個IP封殺,就輸入:` ```markup iptables -I INPUT -s 123.44.55.66 -j DROP ``` 要解封則將-I換成-D即可,前提是[iptables](https://janecc.com/tag/iptables/)已經有這條記錄。如果要想清空封掉的IP地址,可以輸入: ```markup iptables --flush ``` 要新增IP段到封停列表中,使用下面的命令: ```markup iptables -I INPUT -s 121.0.0.0/8 -j DROP ``` 其實也就是將單個IP封停的IP部分換成了Linux的IP段表示式。關於IP段表示式網上有很多詳細解說的,這裡就不提了。 相信有了iptables的幫助,解決小的DDoS之類的攻擊也不在話下! #### 其他常用的命令 編輯 iptables 檔案 ```markup vi /etc/sysconfig/iptables ``` 關閉/開啟/重啟防火牆 ```markup /etc/init.d/iptables stop #stop 關閉 #start 開啟 #restart 重啟 ``` 驗證一下是否規則都已經生效: ```markup iptables -L ``` 儲存並重啟iptables ```markup /etc/rc.d/init.d/iptables save service iptables restart ``` ##### 或者通過host.allow限制特定IP來訪 ```python # 生效是立即發生的,但是對於已經開啟的shell無效,所以一邊留著shell設定,一邊再開shell tail -1 /etc/hosts.allow sshd:39.108.140.0:allow # 允許此IP登陸 tail -1 /etc/hosts.deny sshd:all # 禁止所有機器登陸 tail -1 /etc/ssh/sshd_config allowusers root@ip # 允許某個IP用什麼賬戶登陸,否則登陸不上去 cat /etc/ssh/sshd_config |grep 10086 Port 10086