防火牆簡述
防火牆(firewall)一詞本是建築用於,本意是為了保護建築物不受火災侵害的。被借鑒到了在網絡通信領域中,表示保護局域網或主機不受網絡攻擊的侵害。
防火牆: 工作在主機或者網絡邊緣,對於進出的數據報文按照事先定義好的規則進行檢查,監控,一旦符合標准,我們就按照事先定義好的規則處理動作的一套機制組件叫做(網絡)(主機)防火牆
目前市面上比較常見的有3,4層的防火牆,叫做網絡層防火牆,還有七層的防火牆,其實是代理層的網關.
對於TCP/IP的七層模型來講,我們知道第三層是網絡層,三層的防火牆會在這層對源地址和目標地址進行檢測,但是對於七層的防火牆,不管你是源端口或者目標端口,源地址或者目標地址是什么,都將對你所有的東西進行檢查. 所以對於設計原理來講,七層防火牆更加安全, 但是這卻帶來了效率更低, 所以市面上通常的防火牆方案,都是兩者結合的. 而又由於我們都需要從防火牆所控制的這個口來訪問,所以防火牆的工作效率就成了用戶能訪問數據多少的一個最重要的控制,配置的不好甚至可能成為流量的瓶頸.
根據防范的方式和側重點的不通分為很多種類型, 但總體來講可分為包過濾防火牆和代理服務器兩種類型.
防火牆分類
主機防火牆
工作在某個主機邊緣,主要對進出本主機
報文的分層識別,都是在系統內核級別實現的,故防火牆也工作在單台主機內核空間中[TCP/IP協議棧上],其只能作用於單台主機
網絡防火牆
網絡中的防火牆設備,可分為三種:代理防火牆、包過濾防火牆、狀態監測防火牆。
代理防火牆
代理防火牆是代理內網主機上網的設備,可以是路由器,也可以是一台主機兩塊網卡,一連內網、一連公網,以代替內網主機訪問公網資源,又被稱為nat(網絡地址轉換服務器、或nat堡壘服務器);
工作原理
在應用層實現防火牆功能, 提供部分和傳輸有關的狀態,能完全提供與應用相關的狀態和部分傳輸的信息,他還能處理和管理信息.
包過濾防火牆
包過濾防火牆是檢測所通過數據包,可監測到數據包中源ip、目的ip、源端口、目的端口、標記位等信息,並根據事先制定的通信規則決定數據包是否轉發;
工作原理
在網絡層對數據包進行選擇過濾,采用訪問控制列表(Access control table -ACL)檢查數據流的源地址,目的地址,源和目的端口,IP等信息.
netfilter/iptables(簡稱為iptables)組成Linux平台下的包過濾防火牆,與大多數Linux軟件一樣, 這個包過濾防火牆是免費的, 他可以替代昂貴的商業防火牆解決方案,完成封包過濾,封包重定向和網絡地址轉換(NAT)等功能.
狀態監測防火牆
狀態監測防火牆除了可以監測數據包中的內容外,還可以跟蹤每個客戶的每次通信,當有攻擊數據在開始時偽裝成正常訪問,之后突然開始做攻擊時,會被狀態監測防火牆監測到並加以屏蔽。
在Linux系統中,防火牆工具使用的是iptables,可實現代理防火牆、包(數據報文)過濾防火牆,nat,mangle等規則的功能,而狀態監測防火牆一般是企業購買專用的防火牆設備完成的。
軟件防火牆
軟件邏輯實現
軟件防火牆由工作在通用計算機[即x86系列cpu]上的系統內核通過調用底層通用cpu指令集實現;
硬件防火牆
硬件和軟件邏輯組合實現,為某種特殊功能設計和實現,靈活性差
硬件防火牆使用專業的CPU,其在CPU的硬件級別就能完成對於報文的拆封操作;其只能實現防火牆數據流控制的相關功能;
性能很好[因為其在CPU的指令級別就已經實現了相對復雜的功能,其不用在邏輯層進行復雜的指令組合即可完成對應功能
數據流向
/*
數據包--> 網卡驅動 --> 內核內存空間--> TCP/IP協議棧分析目標IP
-->若是本機ip,則再查看端口並交由相關程序
--> 若不是本機ip,當開啟路由轉發功能后,
內核將會查看本機路由表,將數據包交由對應網卡接口,作為下一跳;
若沒有路由條目,則將此報文交由默認網關,由默認網關將其轉發到相關主機;
*/
報文流向
/*
流入本機:PREROUTING --> INPUT
由本機流出:OUTPUT --> POSTROUTING
轉發:PREROUTING --> FORWARD --> POSTROUTING
*/
netfilter路由功能發生時刻
/*
報文進入本機后:判斷目標主機是?
報文離開本機后:判斷經由哪個接口送往下一站。
*/
Linux內核通信邏輯
通信是進程之間進行的, 客戶端和服務端的程序通過建立tcp連接, 通過套接字進行數據傳輸.
將所有端口開放給所有內部主機,以保證通信的正常進行, 而防火牆為了保證安全, 在所有端口之外進行了限制, 只有某些規定允許的端口才能開放給外部主機進行訪問使用
Linux防火牆的發展:
/*
1.0時代 --> ipfirewall
2.0時代 --> ipchains
3.0時代 --> iptables
4.0時代 --> nftables
*/
Iptables工作原理(四表五鏈)
五鏈
五個鈎子函數(hook functionns),也叫五個規則(rules)鏈(chains) (數據包傳播的路徑)
/*
prerouting 路由前
input 數據包流入口
forward 轉發網卡
output 數據包出口
postrouting 路由后
*/
這是NetFilter規定的五個規則鏈,任何一個數據包,只要經過本機,必將經過五個鏈中的其中一個鏈
防火牆策略一般分為兩種, 一種叫"通"策略,一種叫"堵"策略:
/*
通策略, 默認門是關着的, 必須要定義誰能進.
堵策略,大門是打開的,但是你必須有身份你認證,否則不能進去.
*/
表的概念
我們再想想另外一個問題,我們對每個"鏈"上都放置了一串規則,但是這些規則有些很相似,比如,A類規則都是對IP或者端口的過濾,B類規則是修改報文,那么這個時候,我們是不是能把實現相同功能的規則放在一起呢,必須能的。
我們把具有相同功能的規則的集合叫做"表",所以說,不同功能的規則,我們可以放置在不同的表中進行管理,而iptables已經為我們定義了4種表,每種表對應了不同的功能,而我們定義的規則也都逃脫不了這4種功能的范圍,所以,學習iptables之前,我們必須先搞明白每種表 的作用.
iptables為我們提供了如下規則的分類,或者說,iptables為我們提供了如下"表"
/*
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
數據跟蹤處理
Iptables傳輸數據包過程
1. 當一個數據包進入網卡時, 他首先進入prerouting鏈, 內核根據數據包目的IP判斷是否傳送出去.
2. 如果數據包進入本機, 他就會沿着圖向下移動, 到達input鏈, 數據包到了input鏈后,任何進程都會收到他,本機上運行的程序可以發送數據包, 這些數據包會經過output鏈, 然后到達postrouting鏈輸出
3. 如果數據包要轉發出去,且內核允許轉發,數據包就會如圖所示向右移動,經過Forward鏈, 然后到達Postrouting鏈輸出
iptables/netfilter(這款軟件)是工作在用戶空間的,他可以讓規則進行生效的,本身不是一種服務, 而且規則是立即生效的, 而我們iptables現在被做成了一個服務, 可以進行啟動,停止的, 啟動,則將規則直接生效, 停止,則將規則撤銷.
自定義鏈
iptables還支持自己自定義鏈, 但是自己自定義的鏈, 必須是跟某種特定的鏈關聯起來的, 在一個關卡設定, 指定當有數據的時候專門去找某個特定的鏈來處理, 當那個鏈處理完之后, 再返回,接着在特定的鏈中繼續檢查.只有在被調用時才能發揮作用, 而且如果沒有自定義鏈中的
注意: 規則的次序非常關鍵,檢查規則是按照從上往下的方式進行檢查的
/*
用戶可以刪除自定義的空鏈
默認鏈無法刪除
每個規則都有兩個內置的計數器
被匹配的報文個數
被匹配的報文體積大小之和
*/
表鏈關系
但是我們需要注意的是,某些"鏈"中注定不會包含"某類規則",就像某些"關卡"天生就不具備某些功能一樣,比如,A"關卡"只負責打擊陸地敵人,沒有防空能力,B"關卡"只負責打擊空中敵人,沒有防御步兵的能力,C"關卡"可能比較NB,既能防空,也能防御陸地敵人,D"關卡"最屌,海陸空都能防。
那讓我們來看看,每個"關卡"都有哪些能力,或者說,讓我們看看每個"鏈"上的規則都存在於哪些"表"中。
我們還是以圖為例,先看看prerouting"鏈"上的規則都存在於哪些表中。
這幅圖是什么意思呢?它的意思是說,prerouting"鏈"只擁有nat表、raw表和mangle表所對應的功能,所以,prerouting中的規則只能存放於nat表、raw表和mangle表中。
我們總結一下,每個關卡都擁有什么功能
/*
PREROUTING 的規則可以存在於:raw表,mangle表,nat表。
INPUT 的規則可以存在於:mangle表,filter表,(centos7中還有nat表,centos6中沒有)。
FORWARD 的規則可以存在於:mangle表,filter表。
OUTPUT 的規則可以存在於:raw表mangle表,nat表,filter表。
POSTROUTING 的規則可以存在於:mangle表,nat表。
*/
但是,我們在實際的使用過程中,往往是通過"表"作為操作入口,對規則進行定義的,之所以按照上述過程介紹iptables,是因為從"關卡"的角度更容易從入門的角度理解,但是為了以便在實際使用的時候,更加順暢的理解它們,此處我們還要將各"表"與"鏈"的關系羅列出來,
表(功能) <--> 鏈(鈎子)
/*
raw 表中的規則可以被那些鏈使用: prerouting,output
mangle表中的規則可以被那些鏈使用: prerouting, input, forward,output, postrouting
nat表中的規則可以被那些鏈使用: prerouting, output, postrouting (centos7中還有input,centos6中沒有)
filter表中的規則可以被那些鏈使用: input,forward,output
*/
其實我們還需要注意一點,因為數據包經過一個"鏈"的時候,會將當前鏈的所有規則都匹配一遍,但是匹配時總歸要有順序,我們應該一條一條的去匹配,而且我們說過,相同功能類型的規則會匯聚在一張"表"中,那么,哪些"表"中的規則會放在"鏈"的最前面執行呢,這時候就需要有一個優先級的問題
iptables為我們定義了四張表, 當他們處於同一張鏈時, 執行的優先級如下
/*
prerouting鏈中的規則存放於三張表中, 而這三張表的規則執行優先級如下:
raw --> mangle --> nat
優先級次序(由高而低)
raw --> managle --> nat --> filter
*/
但是我們前面說過,某些鏈天生就不能使用某些表中的規則,所以,4張表中的規則處於同一條鏈的目前只有output鏈,它就是傳說中海陸空都能防守的關卡。
為了更方便的管理,我們還可以在某個表里面創建自定義鏈,將針對某個應用程序所設置的規則放置在這個自定義鏈中,但是自定義鏈接不能直接使用,只能被某個默認的鏈當做動作去調用才能起作用,我們可以這樣想象,自定義鏈就是一段比較"短"的鏈子,這條"短"鏈子上的規則都是針對某個應用程序制定的,但是這條短的鏈子並不能直接使用,而是需要"焊接"在iptables默認定義鏈子上,才能被IPtables使用,這就是為什么默認定義的"鏈"需要把"自定義鏈"當做"動作"去引用的原因。這是后話,后面再聊,在實際使用時我們即可更加的明白。
結合上述所有的描述,我們可以將數據包通過防火牆的流程總結為下:
我們在寫Iptables規則的時候,要時刻牢記這張路由次序,靈活配置規則。
我們將經常用到的對應關系重新寫在此處,方便對應圖例查看。
鏈的規則存放於哪些表中(從鏈到表的對應關系):
/*
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的規則,之前打過一個比方,每條"鏈"都是一個"關卡",每個通過這個"關卡"的報文都要匹配這個關卡上的規則,如果匹配,則對報文進行對應的處理,比如說,你我二人此刻就好像兩個"報文",你我二人此刻都要入關,可是城主有命,只有器宇軒昂的人才能入關,不符合此條件的人不能入關,於是守關將士按照城主制定的"規則",開始打量你我二人,最終,你順利入關了,而我已被拒之門外,因為你符合"器宇軒昂"的標准,所以把你"放行"了,而我不符合標准,所以沒有被放行,其實,"器宇軒昂"就是一種"匹配條件","放行"就是一種"動作","匹配條件"與"動作"組成了規則。
規則由匹配條件和處理動作組成
匹配條件
/*
分為基本匹配條件與擴展匹配條件
基本匹配條件:
源地址Source IP, 目標地址DestinationIP.
擴展匹配條件:
分為
1.隱含擴展: 不用特別指明那個模塊進行的擴展,因為此時用-p {tcp|udp|icmp}
除去上面條件可以用於匹配,還有其他條件可以用於匹配,這些條件泛稱為擴展條件.
這些擴展條件其實是netfilter中的一部分, 只是以模塊的形式存在,如果想使用這些條件,則需要依賴對應的擴展模塊.
源端口Source Port,目標端口Destination Port
2.顯式擴展: 必須指明由那個模塊進行的擴展,在iptables中使用-m選項既可完成功能.
*/
處理動作
處理動作在iptables中被稱為target(這樣說並不准確,我們暫且這樣稱呼),動作也可以分為基本動作和擴展動作.
/*
ACCEPT:允許數據包通過。
DROP:直接丟棄數據包,不給任何回應信息,這時候客戶端會感覺自己的請求泥牛入海了,過了超時時間才會有反應。
REJECT:拒絕數據包通過,必要時會給數據發送端一個響應的信息,客戶端剛請求就會收到拒絕的信息。
SNAT:源地址轉換,解決內網用戶用同一個公網地址上網的問題。
MASQUERADE:是SNAT的一種特殊形式,適用於動態的、臨時會變的ip上。
DNAT:目標地址轉換。
REDIRECT:在本機做端口映射。
LOG:在/var/log/messages文件中記錄日志信息,然后將數據包傳遞給下一條規則,也就是說除了記錄以外不對數據包做任何其他操作,仍然讓下一條規則去匹配。
*/
語法構成
/*
iptables [-t 表名] 選項(增刪) [鏈名] [-m matchaname(匹配型模塊)] [per-match-options(模塊自帶選項)] -j targetname[(操作型模塊)控制類型] [per-target-options(對應選項)]
注意事項
1. 不指定表名時, 默認指filter表.
2. 不指定鏈名時, 默認指表內的所有鏈.
3. 除非設置鏈的默認策略, 否則必須指定匹配條件.
4. 選項,鏈名,控制類型使用大寫字母,其余均小寫
規則組成:
匹配條件 + 處理動作
根據匹配條件嘗試匹配報文,一旦匹配成功,就由定義的處理動作做出匹配.
匹配條件: [盡可能准確指向要處理目標報文類型]
基本匹配條件[內建]
擴展匹配條件[外部擴展模塊]
處理動作:
基本處理動作[內建]
擴展處理動作[外部擴展模塊]
自定義處理機制
*/
規則編寫邏輯
/*
1. 先設置默認規則,全局拒絕或者全局接受[即白名單或黑名單]
2. iptables規則檢查時,是由上而下進行檢查,一個請求報文符合某個條件時, 便被放心,不再接受下面的規則;
3. 對於同一類規則中, 檢查條件更苛刻規則放在前面; 對於不通類的規則[即控制不同服務的規則條目], 訪問請求量更大的放在前面;
! 修改默認規則為DROP之前, 必須先把自己主機IP設置在ssh服務白名單中,否則ssh連接會立刻斷開.
[保險的做法是先定義一條計划任務,過一段時間后將規則清空,以防萬一,確定無誤后,將計划任務刪掉;]
INPUT:iptables -A INPUT -d 本身ip -j REJECT
OUTPUT:iptables -A OUTPUT -s 本身ip -j REJECT
FORWARD:iptables -A FORWARD -d 本身ip -j REJECT
將所有前面未匹配到的規則都拒絕掉,如此就可以避免失誤造成ssh服務被禁止;此外,這樣設置可以使本機可以通過 127.0.0.1 訪問本機;
! 或者可以直接在網卡級別進行設置;若有多個網卡則將其全部寫入一個自定義鏈上,最后調用一下即可;
iptables -A INPUT -i ens33 -j REJECT
iptables -A OUTPUT -o ens33 -j REJECT
添加規則考量點:
1. 要實現那種功能: 判斷添加到那個表上.
2. 報文流經的路徑: 判斷添加到那個鏈上.
鏈:鏈上的規則次序,即為檢查的次序;因此,隱含一定的應用法則;
(1)同類規則(訪問同一應用),匹配范圍小的放上面;
(2)不同類的規則(訪問不同應用),匹配到報文頻率較大的放在上面;
(3)將那些可由一條規則描述的多個規則合並起來;
(4)設置默認規則
iptables是高度模塊化的,其由諸多擴展模塊來實現其檢查條件或處理動作的功能;
rpm -ql iptables --> 在/usr/lib64/xtables/下有許多以'.so'結尾的文件,其中大寫字母的是動作相關模塊,小寫字母是條件相關模塊;其共稱為iptables的擴展;
IPv6為libip6t_開頭的,IPv4的是libipt_開頭的,以libxt_開頭的也適用於ipv4;
*/
規則command(增刪)
/*
添加新的規則:
-A: 在鏈的末尾追加一條規則
-I: 在鏈的開頭(或指定序號)插入一條規則,省略時表示第一條.
-s: --src: 指定源地址,支持連續端口
-s 匹配來源地址IP/MASK,加嘆號"!"表示除這個IP外。
--tcp-flags mask comp 只檢查mask指定的標志位,是逗號分隔的標志位列表; comp: 此列表中出現的標記位必須為1, comp中沒出現, 而mask中出現的必須為0;
--tcp-flags SYN,FIN,ACK,RST SYN,ACK == --syn
SYN為1,其他都為0,意味着三次握手的第一次,有一個特殊的簡要寫法
--syn: 匹配三次握手的第一次
-o 網卡名稱 匹配從這塊網卡流出的數據
-i 網卡名稱 匹配從這塊網卡流入的數據
-d: --dst: 指定目標地址
-P 設置默認策略:iptables -P INPUT (DROP|ACCEPT)
-p: {tcp|udp|icmp}: 指定協議
--icmp-type
0: echo-reply
8: echo-request
udp
--sport
--dport
ip_conntrack: 實時記錄當前主機客戶端,服務端正在建立連接的關系,是什么狀態,
可以只允許本地主機出去的連接必須為已經建立的連接,對別人的響應,否則不放行.
因為是通過IP報文進行的追蹤,tcp,udp都可以應用.
/proc/net/ip_conntrack可以查看建立連接信息,或者iptstate -t
-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: 查看規則時,顯示規則的序號
-v: 顯示詳細信息
-vv: 更詳細
-x: 明確說明多少個字節,顯示計數器精確值
iptables -L -n
Chain INPUT (policy ACCEPT)
[鏈] [策略] [允許]
target prot opt source destination
iptables -n -L -v
Chain INPUT (policy ACCEPT 220 packets, 17378 bytes)
pkts bytes target prot opt in out source destination
chain: [鏈]
policy: [策略]
accept: [允許]
pkts: [被某一條規則匹配到數據包的個數]
bytes: [bytes] 字節數
執行動作
-j
1. ACCEPT: 允許通過
2. DROP: 直接丟棄,不給出任何回應
3. REJECT: 拒絕通過,必要時會給出提示.
4. LOG: 記錄日志信息, 然后傳給下一條規則繼續匹配
5. SNAT: 修改數據包源地址
6. REDIRECT: 端口重定向
7. MASQUERADE: 做地址偽裝(地址轉換)
8. LOG: 日志
9. MARK: 打標記
替換規則
-R CHAIN [num]: 替換指定的規則
刪除,清空規則
-D: 刪除鏈內指定序號(或內容)的一條規則.或者指明規則本身
-F: 清空所有的規則鏈
-R: replace, 替換指定鏈上的指定規則
iptables -D INPUT 3
iptables -n -L INPUT
iptables [-t table] {-A|-C|-D} chain rule-specification
iptables [-t table] -I chain [rulenum] rule-spectification
指定插入第幾條,其后的所有規則都推后;
iptables [-t table] -D chain relunum
iptables [-t table] {-F|-L|-Z} [chain [rulenum]] [options...]
管理鏈
-P CHAIN: 設定指定鏈默認策略
-N: 自定義一個新的空鏈
-X: 刪除一個自定義空鏈
-E: 置零指定鏈中所有規則的計數器
*/
Example
// 先寫好規則,防止自己登錄不上去
iptables -t filter -A INPUT -s 10.211.55.0/24 -d 10.211.55.3 -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -s 10.211.55.3 -d 10.211.55.0/24 -p tcp --sport 22 -j ACCEPT
iptables -t filter -A INPUT -s 192.168.43.0/24 -d 192.168.43.86 -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -s 192.168.43.86 -d 192.168.43.0/24 -p tcp --sport 22 -j ACCEPT
// 允許所有ssh連接的請求
iptables -A INPUT -i ens32 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o ens32 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
/*
我們把iptables的鏈全部DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
當INPUT鏈和OUTPUT鏈都設置成DROP時,對於每一個防火牆規則,我們都應該定義兩個規則。
例如:一個傳入另一個傳出。在下面所有的例子中,由於我們已將DROP設置成INPUT鏈和OUTPUT鏈的默認策略,
每種情況我們都將制定兩條規則。當然,如果你相信你的內部用戶,則可以省略上面的最后一行。
例如:默認不丟棄所有出站的數據包。在這種情況下,對於每一個防火牆規則要求,
你只需要制定一個規則——只對進站的數據包制定規則。
yum -y install httpd && systemctl start httpd
當我們要開通任意IP訪問時候0.0.0.0可以不用寫,默認就是.
開通80端口訪問進出報文規則
iptables -I INPUT -d 10.211.55.3 -p tcp --dport 80 -j ACCEPT
iptables -I OUTPUT -s 10.211.55.3 -p tcp --sport 80 -j ACCEPT
允許ping自己
iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -i lo -j ACCEPT
iptables -A OUTPUT -s 127.0.0.1 -d 127.0.0.1 -o lo -j ACCEPT
iptables -A OUTPUT -s 10.211.55.4 -p icmp --icmp-type 8 -j ACCEPT
iptables -A INPUT -d 10.211.55.4 -p icmp --icmp-type 0 -j ACCEPT
開啟ip_conntrack
注意這個值改大一點,否則並發一高,大批量鏈接超時
sysctl -w net.ipv4.ip_conntrack_max=65535
cat /proc/sys/net/ipv4/ip_conntrack_max
iptables -A INPUT -d 10.211.55.3 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -s 10.211.55.3 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -A INPUT -d 10.211.55.3 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -s 10.211.55.3 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
出去的報文必須是響應報文.
iptables -A INPUT -d 10.211.55.3 -p icmp --icmp-type 8 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -s 10.211.55.3 -p icmp --icmp-type 0 -m state --state ESTABLISHED -j ACCEPT
*/
鏈管理
/*
-N:new,自定義一條新的規則鏈;
iptables [-t tables] -N chain --> 鏈名不能與內置鏈沖突;
Chain in_web_rules (0 references) --> 引用計數,被引用一次加一;
-X:delete,刪除自定義的規則鏈;
iptables [-t tables] -X in_web_rules
1、當一個鏈上有規則時,刪不掉;
2、一個自定義鏈上的引用計數不為0時,刪不掉;
3、內置鏈不能刪;
· 即僅能刪除‘自定義的’ ‘空的’ ‘未被引用’ 的鏈;
-P:Policy,設置默認規則策略,對filter表而言,其默認策略有:
ACCEPT:接受[內建]
DROP:丟棄[內建] --> 能DROP,就別REJECT;使用DROP雖然更安全,會花費更長時間;
REJECT:拒絕[模塊擴展]
-E:重命名自定義鏈;被引用過的自定義鏈不能被重命名,也不能被刪除;
eg:
iptables -N in_web
iptables -E in_web in_web_rules
iptables -X in_web_rules
-F:flush,清空指定鏈上的規則,或一個表上的所有規則
eg:
iptables -F IN_public --> 清除IN_public鏈上的所有規則;
-Z:zero,置零兩個計數器;
*/
保存生效規則
/*
iptables不是服務,但有服務腳本, 服務腳本的主要作用在於管理保存的規則.因為iptables的所有規則定義完成后都保存在內核內存之中.
裝載及移除iptables/netfilter相關的內核模塊:
iptables_nat, iptables_filter,iptables_mangle, iptables_raw,ip_nat,ip_conntrack
重載: systemctl reload iptables --> 默認從/etc/sysconfig/iptables中讀取iptables規則;
! 重載之后,只是規則生效,但是之前手動加載到內核的模塊,不會被重新載入;
! 需要寫腳本進行重載,或者更直接可以將所有iptables命令寫入腳本,讓其開機自動執行一遍;
service iptables save
iptables-save > /etc/sysconfig/iptables.2020.11.09
iptables-restore < /etc/sysconfig/iptables.2020.11.09
*/
常用案例
iptables禁止某IP訪問
在CentOS下封停IP,有封殺網段和封殺單個IP兩種形式。一般來說,現在的攻擊者不會使用一個網段的IP來攻擊(太招搖了),IP一般都是散列的。於是下面就詳細說明一下封殺單個IP的命令,和解封單個IP的命令。
在CentOS下,使用ipteables來維護IP規則表。要封停或者是解封IP,其實就是在IP規則表中對入站部分的規則進行添加操作。
要封停一個IP,使用下面這條命令:
iptables -I INPUT -s 172.18.80.5 -j DROP
# 也可以換成一個網段
iptables -I INPUT -s ***.***.***.*** -j DROP
要解封一個IP,使用下面這條命令
iptables -I INPUT -s 172.18.80.5 -j DROP
iptables -D INPUT -s ***.***.***.*** -j DROP
參數-I是表示Insert(添加),-D表示Delete(刪除)。后面跟的是規則,INPUT表示入站,...表示要封停的IP,DROP表示放棄連接。
此外,還可以使用下面的命令來查看當前的IP規則表:
iptables --list
比如現在要將123.44.55.66這個IP封殺,就輸入:
iptables -I INPUT -s 123.44.55.66 -j DROP
要解封則將-I換成-D即可,前提是iptables已經有這條記錄。如果要想清空封掉的IP地址,可以輸入:
iptables --flush
要添加IP段到封停列表中,使用下面的命令:
iptables -I INPUT -s 121.0.0.0/8 -j DROP
其實也就是將單個IP封停的IP部分換成了Linux的IP段表達式。關於IP段表達式網上有很多詳細解說的,這里就不提了。
僅允許指定網絡的ssh連接
[root@86 ~]# iptables -A INPUT -i ens32 -p tcp -s 192.168.43.84 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
[root@86 ~]# iptables -A OUTPUT -o ens32 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
允許http和https的連接請求
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
// 允許所有來自web - https的連接請求
iptables -A INPUT -i eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
使用multiport將多個規則
允許多個端口從外界連入,除了為每個端口都寫一條獨立的規則外,我們可以用multiport將其組合成一條規則。如下所示: 例:允許所有ssh,http,https的流量訪問
iptables -A INPUT -i eth0 -p tcp -m multiport --dports 22,80,443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp -m multiport --sports 22,80,443 -m state --state ESTABLISHED -j ACCEPT
允許從本地發起的ssh
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
# 請注意,這與允許ssh連入的規則略有不同。本例在OUTPUT鏈上,我們允許NEW和ESTABLISHED狀態。
# 在INPUT鏈上,我們只允許ESTABLISHED狀態。ssh連入的規則與之相反。
僅允許從本地發起一個指定網絡域的ssh請求
# 僅允許從內部連接到網域192.168.100.0/24
iptables -A OUTPUT -o eth0 -p tcp -d 192.168.100.0/24 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
允許從本地發起的https連接請求
# 下面的規則允許輸出安全的網絡流量。如果你想允許用戶訪問互聯網,這是非常有必要的。
# 在服務器上,這些規則能讓你使用wget從外部下載一些文件
iptables -A OUTPUT -o eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
# 對於HTTP web流量的外聯請求,只需要將上述命令中的端口從443改成80即可。
負載均衡傳入的網絡流量
# 使用iptables可以實現傳入web流量的負載均衡,我們可以傳入web流量負載平衡使用iptables防火牆規則。
# 例:使用iptables nth將HTTPS流量負載平衡至三個不同的ip地址.
iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 0 -j DNAT --to-destination 192.168.1.101:443
iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 1 -j DNAT --to-destination 192.168.1.102:443
iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 2 -j DNAT --to-destination 192.168.1.103:443
允許內部主機ping通內部主機
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
允許內部主機ping外部主機
iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
允許回環訪問
# 在服務器上允許127.0.0.1回環訪問。
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
允許內部網絡與外部網絡通信
防火牆服務器上的其中一個網卡連接到外部,另一個網卡連接到內部服務器,使用以下規則允許內部網絡與外部網絡的通信。此例中,eth1連接到外部網絡(互聯網),eth0連接到內部網絡(例如:192.168.1.x)。
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
允許出站的DNS連接
iptables -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT
iptables -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT
允許NIS連接
如果你使用NIS管理用戶帳戶,你需要允許NIS連接。如果你不允許NIS相關的ypbind連接請求,即使SSH連接請求已被允許,用戶仍然無法登錄。NIS的端口是動態的,先使用命令rpcinfo –p來知道端口號,此例中為853和850端口。 rpcinfo -p | grep ypbind 例:允許來自111端口以及ypbind使用端口的連接請求
iptables -A INPUT -p tcp --dport 111 -j ACCEPT
iptables -A INPUT -p udp --dport 111 -j ACCEPT
iptables -A INPUT -p tcp --dport 853 -j ACCEPT
iptables -A INPUT -p udp --dport 853 -j ACCEPT
iptables -A INPUT -p tcp --dport 850 -j ACCEPT
iptables -A INPUT -p udp --dport 850 -j ACCEPT
# 當你重啟ypbind之后端口將不同,上述命令將無效。有兩種解決方案:
# 1)使用你NIS的靜態IP
# 2)編寫shell腳本通過“rpcinfo - p”命令自動獲取動態端口號,並在上述iptables規則中使用。
允許指定網絡的rsync連接請求
允許來自網絡192.168.101.0/24的rsync連接請求
iptables -A INPUT -i eth0 -p tcp -s 192.168.101.0/24 --dport 873 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 873 -m state --state ESTABLISHED -j ACCEPT
允許來自指定網絡的Mysql請求
很多情況下,MySQL數據庫與web服務跑在同一台服務器上。有時候我們僅希望DBA和開發人員從內部網絡(192.168.100.0/24)直接登錄數據庫,可嘗試以下命令:
iptables -A INPUT -i eth0 -p tcp -s 192.168.100.0/24 --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 3306 -m state --state ESTABLISHED -j ACCEPT
允許Sendmail,PostFix郵件服務
Sendmail和postfix都使用了25端口,因此我們只需要允許來自25端口的連接請求即可。
iptables -A INPUT -i eth0 -p tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT
允許IMAP和IMAPS
# 允許IMAP/IMAP2流量,端口為143
iptables -A INPUT -i eth0 -p tcp --dport 143 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 143 -m state --state ESTABLISHED -j ACCEPT
# 允許IMAPS流量,端口為993
iptables -A INPUT -i eth0 -p tcp --dport 993 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 993 -m state --state ESTABLISHED -j ACCEPT
允許POP3 和POP3S
# 允許POP3訪問
iptables -A INPUT -i eth0 -p tcp --dport 110 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 110 -m state --state ESTABLISHED -j ACCEPT
# 允許POP3S訪問
iptables -A INPUT -i eth0 -p tcp --dport 995 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 995 -m state --state ESTABLISHED -j ACCEPT
防止Dos攻擊
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
# 上述例子中:
# -m limit: 啟用limit擴展
# –limit 25/minute: 允許最多每分鍾25個連接(根據需求更改)。
# –limit-burst 100: 只有當連接達到limit-burst水平(此例為100)時才啟用上述limit/minute限制。
端口轉發
將來自422端口的流量全部轉到22端口。 這意味着我們既能通過422端口又能通過22端口進行ssh連接
iptables -t nat -A PREROUTING -p tcp -d 192.168.102.37 --dport 422 -j DNAT --to 192.168.102.37:22
# 除此之外,還需要允許連接到422端口的請求
iptables -A INPUT -i eth0 -p tcp --dport 422 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 422 -m state --state ESTABLISHED -j ACCEPT
iptables常用擴展模塊
iprangne
/*
-m iprange
--src-range
--dst-range
iptables -A INPUT -p tcp -m iprange --src-range 10.211.55.4-10.211.55.5 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
*/
connlimit
/*
連接數限制(connlimit)
限定每一個IP最多發起多少個連接數.
! --connlimit-above n
iptables -A INPUT -d 10.211.55.2 -p tcp --dport 80 -m connlimit --connlimit-above 2 -j ACCEPT
tc
令牌桶機制限流:
iptables -I INPUT -d 10.211.55.4 -p tcp --dport 22 -m limit --limit 3/minute --limit-burst 3 -j ACCEPT
iptables -A INPUT -d 10.211.55.4 -p tcp --dport 80 -m con
*/
string
限定用戶訪問字符串
/*
--algo {bm|kmp}
--string "STRING"
無法檢查文件內容
iptables -I OUTPUT -p tcp -m string --string "qq.com" --algo bm -j DROP
iptables -I OUTPUT -p udp -m string --string "qq.com" --algo bm -j DROP
這樣就無法訪問與QQ相關的業務了,但是代理好像還是可以
如果是匹配到對應test頁面名字就拒絕請求
iptables -I INPUT -d 10.211.55.3 -m string --algo kmp --string "test" -j REJECT
響應的報文是不會經過INPUT的,用戶請求的報文也沒有包含,所以需要把包改成對應名字, 除非加到OUTPUT
iptables -I OUTPUT -s 10.211.55.3 -m string --algo kmp --string "zhou" -j REJECT
*/
Log
/*
iptables -I INPUT 4 -d 10.211.55.3 -p icmp --icmp-type 8 -j LOG --log-prefix "--firewall log for icmp--"
*/
recent
利用iptables的recent模塊抵御DOS攻擊
/*
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j LOG --log-prefix "SSH Attach: "
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP
*/
cat /proc/net/xt_recent/SSH
src=192.168.43.219 ttl: 64 last_seen: 4295139283 oldest_pkt: 5 4295096752, 4295121813, 4295126037, 4295138280, 4295139283
// 一個IP連接三次后再去連接就會被拒絕
ssh 192.168.43.86
yssh: connect to host 192.168.43.86 port 22: Connection timed out
/*
利用conlimit模塊將單IP的並發設置為3,會誤殺使用NAT上網的用戶,可以根據實際情況增大該值
利用recent和state模塊限制單IP在300s內只能與本機建立3個新連接, 被限制五分鍾后即可恢復訪問.
上面第二句記錄tcp 22端口的新連接, 記錄名稱為SSH --set記錄數據包的來源IP,如果IP已經存在將更新已經存在的條目.
第三句是指SSH記錄中的IP, 300s內發起超過3次連接則拒絕此IP的連接
--update 是指每次建立連接都更新列表
--seconds必須與 --rcheck或者--update同時使用
--hitcount必須與--rcheck或者--update同時使用
*/
記錄日志
/*
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --name SSH --second 300 --hitcount 3 -j LOG --log-prefix "SSH Attack"
*/
NAT表
主要功能
1、為了隱藏主機;
2、解決了ip地址短缺的問題;
問題:
當內外網將開啟路由轉發的Linux作為網關進行通信時,Linux對數據包並不會做任何改變,故內網主機的IP會暴露;黑客主機可以通過掃描工具對此內網主機ip進行掃描,並滲透;
解決:
nat表的功能可以實現,將經過自身的數據包進行改變,將其中的源地址修改為自身的ip,以此實現隱藏內網主機ip的功能;
nat表在修改數據包ip的同時,會將相關記錄在內核內存中的連接追蹤表中,當回應數據包到達自身時,其又會將數據包目的ip修改為內網主機ip,從而實現內網主機的正常通信
只需要關注請求的數據報文封裝信息,因為響應的數據報文是由nat表的內建工作機制控制的,一般情況下無需人為干預(連接追蹤機制)
被nat表所匹配到的數據報文,內核會修改報文的ip和端口,為了讓轉發機能在接收到返回報文后知道將此報文發送至何處,需要開啟連接追蹤機制;所謂連接追蹤機制就是在內核內存空間中,開辟一塊空間用於存放連接追蹤表;轉發機在修改報文ip和端口的同時,會在追蹤表中進行記錄,信息包括:請求的源地址,源端口,目標地址,目標端口,及報文序列號等;當響應報文到達時,轉發機會根據響應報文中的源地址和端口查看此表,將相應轉發到對應的服務器;
/*
iptables -N clean_in
iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP
iptables -A clean_in -p tcp ! --syn -m state --state NEW -j DROP
*/
NAT類型(SNAT)
源地址轉換
過程
內網主機網關指向NAT轉發主機的內網IP, 當內網主機訪問外網時,數據包經NAT轉發主機, NAT轉發主機開啟內核轉發機制, 並且在NAT表上設置相關規則, 同時打開鏈接追蹤機制,由NAT轉發主機的內核對數據包的源IP進行修改, 將其改為自身的IP, 並發送至請求的目標主機. 當響應報文返回時, 其目標ip為nat轉發主機ip,nat轉發主機收到后,根據內核中記錄的連接追蹤表,將此數據包轉發給對應的內網主機,從而實現內網主機的nat通信.
特點
/*
只能在POSTROUTING鏈上做:
原因:
1. 在POSTROUTING上的數據包,是已經被路由過的,其流向都已經確定.
2. 第二次路由之前, 此數據包將要從那塊網卡出去並不確定, 故只能在第二次路由之后的POSTROUTING上進行SNAT.
*/
應用場景
/*
SNAT策略的典型應用環境
區域網主機共享單個公網IP地址接入Internet
SNAT策略的原理
源地址轉換, Source Network Address Translation
修改數據包的源地址
*/
NAT類型(DNAT)
目標地址轉換
服務器通過nat轉發主機,向外網提供服務,對外提供的服務ip是nat網關的IP,客戶端向nat網關發起請求,由nat網關根據請求的端口,以及自身規則,將數據包的目標ip地址轉換為內網真實服務器ip;真實服務器的網關指向nat網關,當真實服務器回復響應數據包時,其目標ip地址是客戶端的ip,而其源地址是自身ip,當通過nat網關時,由nat網關根據自身記錄的連接追蹤表,將源地址改為自身ip,發送給客戶端,如此可以實現對內網服務器的隱藏;
特點
/*
1. 只能在PREROUTING上做.
2. NAT主機本身並不需要監聽任何端口, 其內核自身就能通過數據包識別請求報文的請求目標端口.
[無法通過ss,netstat等網絡工具看到開放的監聽端口]
3. 所設置的規則只對某些端口生效: [因為其本質就像是一個四層的代理]
原因: 因為數據包都是發給NAT網關本機的,若不在第一次路由之前做,有可能會被轉發到自身的內核空間中.
*/
PAT[端口地址轉換]
過程
在DNAT的基礎上,對port也進行修改, 訪問nat網關某個port的請求, 會被映射到后端真實服務器的真實port,返回時,再將目標端口修改為自身端口.
特點
/*
只能在PREROUTING上做.
原因: 因為數據包都是發給nat網關本機的,若不在第一次路由之前做,將會被轉發到自身的內核空間中;
*/
與數據包過濾結合
SNAT
SNAT和DNAT都會經過FORWARD,在FORWARD上配置iptables規則能實現包的過濾功能:
/*
--使用方式: [SNAT和DNAT一般不不會在同一台主機上同時使用]
SNAT:[一般開放所有服務的所有端口,-j]
選項:
--to-source [ipaddr[-ipaddr]] [:port[-port]]
此選項用來定義要將原地址轉換成什么地址對外進行訪問,可以是一個地址區間[輪流使用];
--ramdom
當指定一個地址范圍或多個地址作為原地址時, 將會隨機進行挑選,而不是輪訓.
--persistent
對於同一個客戶端,其第一次訪問時所分配的ip將被記錄下來, 今后此客戶端的每一個訪問都將使用此IP;
eg:
iptables -t nat -A POSTROUTING -s 192.168.206.135 -j SNAT --to-source 10.0.128.50.
在POSTROUTING鏈上做設置, 數據包的源地址是192.168.206.0/24的, 將會使用10.0.128.50作為源IP轉發到目的IP上.
MASQUERADE
SNAT場景中,當外網地址不固定時,使用此動作.
應用於POSTROUTING鏈上的規則,實現原地址轉換.
*/
DNAT
[一般只開放有限協議的有限端口] --> PAT是DNAT的一種延伸,可以對端口進行修改
/*
選項:
--to-destination
指定將目標地址修改為后端真實服務器IP
eg: iptables -t nat -A PREROUTING -d 10.0.128.50 -p tcp --dport 80 -j DNAT --to-destination 192.168.206.135
PEDIRECT:
作用:
此動作用於單台主機上,通過修改數據包的目標端口實現映射.
特點:
工作在PREROUTING和OUTPUT鏈上;
因為其要在請求數據包被路由之前對數據包中的目標端口進行修改,以此改變數據包的流向;
eg:
iptables -t nat -A PREROUTING -d 10.0.128.49 -p tcp --dport 80 -j REDIRECT --to-ports 8080
*/
Linux作為網絡防火牆
當Linux作為網絡防火牆時,目標不是本機的報文,將會在內核中被分配到對應的網卡接口;
其所依賴的規則為路由表:
在路由器中,數據包的流向通過路由表來決定,不同的目標ip將會從對應的網卡上被分發出去;
路由表的生成:
/*
1、在小規模的內網中,或專用網絡中,可以由管理人員通過添加路由條目的方式設置靜態路由;
2、更為普遍的方式是,通過專用的協議,從其他路由器上,獲取共享的路由信息,動態生成路由條目;
優點:
[這種方式可以動態的判斷哪些路由線路是失效的,會將對應的路由條目標記為不可用]
缺點:
1) [這種方式會消耗額外的網絡帶寬,因為其路由條目的生成過程也是需要發送網絡報文的]
2) [在本地需要安裝專門的應用程序后,才能完成這種復雜功能,對於系統資源有一定消耗(此種應用程序可以提供相關的協議和算法)]
--> 如GNU項目的"zebra"[斑馬];
他可以基於TCP/IP的路由協議,將Linux變成一台全功能路由器。其所支持的協議包括:RIP,OSPF,BGP
~ 擴展:
動態路由條目生成的常用協議包括:
RIP2:矢量的
-->根據所要經過的網關數量來判斷最優線路;
[但是這樣判斷出的最優線路所花費時間並不一定最短,因為某些鏈路可能會堵塞]
OSPF(開放式最短路徑優先):鏈路狀態
-->判斷能到達目標的線路中,哪條線路是最通暢的;
...還有其他很多類似的算法和協議;
3 因為其工作在通用架構cpu上,故其對於數據報文轉發的效率並不高;[只能承擔壓力較輕的數據轉發]
*/
數據流經過程
/*
->PREROUTING,對數據包進行初步操作;
-->進行路由,拆數據包到網絡層,判斷數據包目標ip是否是本機ip。
若是,則路由進INPUT鏈,進入本機;
若不是,則數據包進入FORWARD鏈;由 FRORWARD的相關規則進行匹配過濾;
再次路由,對不同的數據包進行分析,根據路由表來規定,將數據包從哪個網卡發送到下一跳;
POSTROUTING,
進入網卡隊列等待發送
所以,過濾規則的設置,只能在FORWARD之上進行設置;
FORWARD鏈規則,不論正向還是反向,其都要經過FORWARD,故其規則的設置是通過數據流向來進行定義的;
根據state,即狀態匹配擴展模塊來實現;
在FORWARD這一條鏈上,定義一個ESTABLISHED,和一條NEW,新請求接受判斷,已建立連接的請求直接放過;
*/
Example
環境
/*
內網主機:192.168.206.135
Linux網絡交換機:
ens33 10.0.128.50
ens37 192.168.206.133
外網主機:10.0.128.49
內網主機網關指向防火牆的ens37,外網主機網關指向防火牆的ens33;
網絡防火牆打開核心轉發功能;
內外網主機可以相互ping通,並且服務也正常開啟
配置外網主機能訪問內網某台主機的相關服務:
*/
配置Linux網絡交換機
vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
sysctl -p /etc/sysctl.conf
[root@86 network-scripts]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:0b:ea:c3 brd ff:ff:ff:ff:ff:ff
inet 192.168.43.86/24 brd 192.168.43.255 scope global dynamic ens32
valid_lft 2951sec preferred_lft 2951sec
3: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:0b:ea:cd brd ff:ff:ff:ff:ff:ff
inet 172.18.80.2/24 brd 172.18.80.255 scope global ens34
valid_lft forever preferred_lft forever
[root@86 network-scripts]# cat ifcfg-ens32
BOOTPROTO="dhcp"
NAME="ens32"
DEVICE="ens32"
ONBOOT="yes"
[root@86 network-scripts]# cat ifcfg-ens34
IPADDR=172.18.80.2
NETMASK=255.255.255.0
DNS1=114.114.114.114
BOOTPROTO="none"
NAME="ens34"
DEVICE="ens34"
ONBOOT="yes"
配置模擬內網機器
[root@47 network-scripts]# cat ifcfg-ens32
IPADDR=172.18.80.3
NETMASK=255.255.255.0
GATEWAY=172.18.80.2
DNS1=114.114.114.114
BOOTPROTO="none"
NAME="ens32"
DEVICE="ens32"
ONBOOT="yes"
[root@47 network-scripts]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.18.80.2 0.0.0.0 UG 100 0 0 ens32
172.18.80.0 0.0.0.0 255.255.255.0 U 100 0 0 ens32
外網主機
[root@219 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:27:24:ef brd ff:ff:ff:ff:ff:ff
inet 192.168.43.219/24 brd 192.168.43.255 scope global dynamic ens32
valid_lft 3024sec preferred_lft 3024sec
SNAT_Example
# 客戶端本來不通的
[root@47 network-scripts]# ping baidu.com
^C
[root@47 network-scripts]# ssh 192.168.43.219
^C
# 通過防火牆轉發
[root@86 network-scripts]# iptables -t nat -A POSTROUTING -s 172.18.80.0/24 -o ens32 -j SNAT --to-source 192.168.43.86
# 客戶端測試
[root@47 network-scripts]# curl 192.168.43.219 -I
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Wed, 11 Nov 2020 08:44:12 GMT
Content-Type: text/html
Content-Length: 4833
Last-Modified: Fri, 16 May 2014 15:12:48 GMT
Connection: keep-alive
ETag: "53762af0-12e1"
Accept-Ranges: bytes
[root@47 network-scripts]# ping baidu.com
PING baidu.com (220.181.38.148) 56(84) bytes of data.
64 bytes from 220.181.38.148 (220.181.38.148): icmp_seq=1 ttl=49 time=7.12 ms
# ping: unknown host www.baidu.com要是出現這個問題就添加一個DNS服務器地址/etc/resolv.conf也可以寫在和主機一起的配置文件當中,DNS地址最好是服務器的DNS地址。
# server端使用地址偽裝
[root@86 network-scripts]# iptables -t nat -A POSTROUTING -s 172.18.80.0/24 -o ens32 -j MASQUERADE
# 客戶端測試效果一樣
# 地址偽裝技術更加接近我們實際的工作生活當中因為我們撥號上網有可能我們使用的公網IP就發生了變化。
DNAT_Example
/*
區域網的Web服務能夠訪問Internet
網關的外網地址有正確的DNS解析記錄
Linux網關支持IP路由支持
編寫DNAT轉換規則
iptables -t nat -A PREROUTING -i eth0 -d 218.29.30.31 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.6
*/
編寫DNAT規則
iptables -t nat -A PREROUTING -i ens34 -d 172.18.80.2 -p tcp --dport 80 -j DNAT --to-destination 192.168.43.86
[root@86 network-scripts]# iptables -nL -t nat
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 172.18.80.2 tcp dpt:80 to:192.168.43.219
DNAT tcp -- 0.0.0.0/0 172.18.80.2 tcp dpt:80 to:192.168.43.86
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.18.80.0/24 0.0.0.0/0
Commond
/*
iptables -A FORWARD -j REJECT
iptables -I FORWARD 2 -d 172.18.80.3 -s 192.168.43.219 -p tcp -m multiport --dports 21,22,23,80,139,445,3306 -m state --state NEW -j ACCEPT
iptables -I FORWARD 3 -d 172.18.80.3 -s 192.168.43.219 -p udp --dport 137:138 -m state --state NEW -j ACCEPT
iptables -I FORWARD 1 -d -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -I FORWARD 4 -s 172.18.80.0/24 -m state --state NEW -j ACCEPT
iptables -A FORWARD -j REJECT
iptables -I FORWARD 2 -d 192.168.206.135 -s 10.0.128.49 -p tcp -m multiport --dports 21,22,23,80,139,445,3306 -m state --state NEW -j ACCEPT
iptables -I FORWARD 3 -d 192.168.206.135 -s 10.0.128.49 -p udp --dport 137:138 -m state --state NEW -j ACCEPT
iptables -I FORWARD 1 -d -d 172.18.80.3 -s 192.168.43.219 -m state --state ESTABLISHED,RELATED -j ACCEPT
配置內網主機訪問外網一切服務:
iptables -I FORWARD 4 -s 192.168.206.0/24 -m state --state NEW -j ACCEPT
配置Linux防火牆支持ftp服務,加載內核模塊:
modprobe nf_conntrack_ftp
[/etc/sysconfig/iptables-config]
--->在此配置文件中的 IPTABLES_MODULES="" 中添加模塊類型即可實現啟動自動加載
!!只適用於FORWARD鏈
iptables -t nat -A PREROUTING -i ens34 -d 172.18.80.2 -p tcp --dport 80 -j DNAT --to-destination 192.168.43.86
*/
或者通過host.allow限制特定IP來訪
# 生效是立即發生的,但是對於已經打開的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