netfilter介紹 防火牆是作用與內網和外網之間,根據定義的策略來過濾流量的軟體或者硬體。在Linux內核中,自帶了防火牆模塊netfilter,通過netfilter可以是實現網路流量的過過濾,以及NAT、連接跟蹤等功能。 通過用戶空間的iptables、firewalld等工具,可以實現相關 ...
netfilter介紹
防火牆是作用與內網和外網之間,根據定義的策略來過濾流量的軟體或者硬體。在Linux內核中,自帶了防火牆模塊netfilter,通過netfilter可以是實現網路流量的過過濾,以及NAT、連接跟蹤等功能。
通過用戶空間的iptables、firewalld等工具,可以實現相關規則的定義,將這些規則傳遞給內核的netfilter框架,實現網路數據包的處理。
netfilter五個鉤子
用戶空間工具允許管理員定義規則,這些規則隨後會與 netfilter 的五個鉤子函數之一關聯。當數據包在網路堆棧中流動併到達某個鉤子點時,netfilter 根據與該鉤子關聯的規則對數據包進行處理。
這五個鉤子函數位於網路堆棧的不同位置:
1、 PREROUTING :這是數據包首先到達的地方,即它在路由決策之前被捕獲
2、 INPUT :用於處理目標是本地系統的數據包
3、 FORWARD :用於處理要被路由轉發的數據包,即它們既不是發往本地系統,也不是從本地系統發出的
4、 OUTPUT :用於處理從本地系統發出的數據包,即在數據包離開系統之前
5、 POSTROUTING :在數據包被路由之後捕獲,即在它離開系統之前
iptables
一般用戶空間常用的防火牆管理工具是iptables,除此之外還有firewalld、nettable等。一般情況下,會用iptables就行了。
使用iptables編寫流量過濾規則前,我們需要先知道iptables的三個概念:規則、規則鏈和表
-
規則:就是一種數據流量的匹配策略。每條規則由兩部分組成:匹配條件+執行動作
-
規則鏈:鏈是一組規則的有序集合。匹配時按順序與鏈中的規則進行匹配,直到它與某個規則匹配或到達鏈的末尾為止
-
表:表是將若幹規則鏈按照其功能進行分類的方式。每個表都專註於特定類型的任務,例如過濾、網路地址轉換等。
一個數據包先進入一個特定的表,然後按順序遍歷該表中的規則鏈,在每個鏈中按順序與規則進行匹配,直到找到一個匹配項或到達鏈的末尾為止。
說明:
數據包不是隨機地進入某個表,而是基於數據包的處理階段和網路堆棧中的位置進入特定的表。netfilter框架定義了幾個預定的鉤子點(hooks),這些鉤子點決定了數據包何時應該被檢查和如何被處理。
鉤子和表的對應關係如下:
預設情況下,netfilter為它的五個鉤子提供了預設的鏈,這個鏈和鉤子同名。例如 INPUT 鉤子與 INPUT 鏈關聯。當數據包准備進入本地系統時,會觸發此鏈。
-
filter 表:主要用於數據包過濾。此表通常包含鏈如 INPUT、OUTPUT 和 FORWARD。例如,進入本機的數據包將會遍歷 INPUT 鏈。
-
nat 表:用於網路地址轉換 (NAT)。此表與 PREROUTING (用於目的地址轉換)和 POSTROUTING (用於源地址轉換)鏈相關聯。例如,當數據包首次到達系統時,它可能會被送到 nat 表的 PREROUTING 鏈來決定是否需要進行目標地址的轉換。
-
mangle 表:用於特殊的數據包修改,如更改TOS欄位。它有多個鏈,如 PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING 等。
-
raw 表:用於配置例外,避免連接跟蹤。此表與 PREROUTING 和 OUTPUT 鏈相關聯。
實現流量過濾
定義規則
iptables -t 指定表名 -I或-A 指定規則鏈名 指定匹配條件 -j 指定處理動作
說明:
-
-I 表示將該規則插入規則鏈的前面,數據流量匹配規則鏈的時候最先就會匹配到該規則
-
-A 表示將該規則插入規則鏈的末尾,最後才會被匹配到
例如:新增一條規則,實現拒絕10.0.0.11主機的報文
iptables -t filter -I INPUT -s 10.0.0.11 -j DROP
-
當處理動作是DROP時,符合這條規則的數據流量都會被丟棄。
-
通過 -s 參數指定的就是數據流量的源地址,如果要指定目標地址的話需要使用 -d參數
例如:新增一條規則,如果目標地址是10.0.0.11的報文,就丟棄
iptables -A INPUT -d 10.0.0.11 -j DROP
丟棄目標地址為10.0.0.11的報文,也應該在INPUT鏈中添加這個規則,因為INPUT鏈是處理到達本機的數據包的規則鏈。
iptables中,匹配條件分為兩種,基本匹配和擴展匹配。
-
基本匹配:iptables這個工具預設就自帶的不需要載入任何額外的模塊。包括地址匹配、介面匹配和協議匹配
-
擴展匹配:iptable預設沒帶由iptables的模塊系統提供,所以使用擴展匹配的時候需要指定模塊名稱,擴展匹配允許使用更複雜、更特定的匹配條件。
基本匹配條件使用:
-
地址匹配:使用 -s 參數指定源地址 使用 -d參數指定目標地址
-
介面匹配:使用 -i 參數指定數據流量從那張網卡進來,使用-o參數指定匹配數據
擴展匹配條件私用:
iptables的擴展匹配模塊是放在 /usr/lib/x86_64-linux-gnu(ubuntu)或/usr/lib64/xtables/*.so(RedHat系列)中的,iptables工具通過 -m 參數即可調用這些擴展模塊。
-
埠匹配:如果要匹配埠的話需要用到multiport模塊,提供了三個常用的參數。--sports 指定源埠,--dports 指定目標埠。--ports 指定埠(不區分源或目標)。這個模塊有一個特點就是可以離散方式定義多埠匹配,最多指定15個埠
-
協議匹配:tcp協議匹配使用tcp模塊,udp協議匹配使用udp模塊,icmp協議匹配使用icmp模塊,因為模塊名稱和協議類型是一樣的,所以可以忽略-m指定模塊,直接用-p指定協議類型就行了。這些模塊也提供了 --sport 參數指定源埠,--dport參數指定目標埠,但是這些埠可以是單個或者一個範圍。就是不能是離散的。例如: --sport 11,12,13 這種就是錯的。
例如:禁止10.0.0.29的22、80、1884、1883埠的數據
iptables -t filter -I INPUT -s 10.0.0.29 -p tcp -m multiport --ports 22,80,1884,1883 -j DROP
例如:禁止10.0.0.29通過ssh訪問本機
iptables -t filter -I INPUT -s 10.0.0.29 -ptcp --dport 22 -j DROP
說明: 埠是傳輸層的概念,所以要使用 -p來指定協議類型為tcp才行。又因為tcp模塊和協議名稱一致,所以可以省略 -m tcp
當指定的規則匹配到數據流浪後,有三種處理動作來處理匹配到的流量:
-
ACCEPT:放行
-
DROP:直接丟棄
-
REJECT:拒絕,會高度客戶端請求流量被拒絕了
查看規則
要查看規則,首先需要使用 -t 參數指定要查看哪張表的規則,然後使用 -vnL 這三個參數就可以查看規則的信息信息了。
iptables -t 表名 -vnL
刪除規則
刪除規則使用的是 -D 參數。刪除規則有兩種方式,一種就是先查看規則的編號,然後通過編號進行刪除。還有一種就是根據具體的匹配條件與動作刪除規則
例如:刪除INPUT鏈中編號為1的規則
iptables -t filter -D INPUT 1
例如:刪除filter表中,INPUT鏈上,源地址是10.0.0.11,處理動作是DROP的這條規則
iptables -t filter -D INPUT -s 10.0.0.11 -j DROP
清除鏈表上的所有規則:
通過 -F 參數可以用來清除指定規則鏈上的所有規則,如果不指定表的話,預設操作的就是filter表。
iptables -t 表明 -F 鏈名
例如:清除filter表中,INPUT鏈上的所有規則
iptables -t filter -F INPUT
修改預設策略
如果要修改某個規則鏈的預設策略,可以通過 -P 參數 來實現。當鏈中沒有任何規則時,防火牆會按照預設動作處理報文
iptables -P 鏈名 預設的策略
例如:修改filter表中的INPT鏈的預設策略為DROP
iptables -t filter -P INPUT DROP
實現黑白名單
黑名單:被指定的用戶被拒絕,其它用戶被允許。實現方式就是將指定規則鏈的預設策略改為ACCEPT,然後加入的匹配規則的策略為DROP或者REJECT
白名單:預設就是拒絕,指定的用戶才會被運行。將指定鏈的預設的匹配規則設置為REJECT,加入的規則設置為ACCEPT。
例如:只開放 22、80、8000、8001、1883、1884、9001、9100、9802埠
# 需要先保證當前的遠程不會斷
iptables -t filter -I INPUT -s 10.0.0.1 -j ACCEPT
# 修改INPUT鏈預設的策略
iptables -t filter -P INPUT DROP
# 添加運行通過的數據報文
iptables -t filter -A INPUT -m multiport -p tcp --dports 22,8000,8001,80,1883,1884,9001,9100,9802 -j ACCEPT
iptables -t filter -A INPUT -m multiport -p udp --dports 22,8000,8001,80,1883,1884,9001,9100,9802 -j ACCEPT
保存規則
預設通過iptables編寫的規則,重啟系統後就失效了,如果需要實現持久化生效,需要藉助特定的工具保存才行。
(1)通過 iptables-save 保存規則
iptables-save 命令可以將當前的 iptables 配置輸出到標準輸出。你可以將其重定向到一個文件以保存當前的規則集。
sudo iptables-save > /path/to/your/iptables.rules
(2)通過 iptables-restore 恢復規則
sudo iptables-restore < /path/to/your/iptables.rules
說明:需要保證 restore恢復規則這條命令開機能自動執行,可以加入rc.loca,也可以加入shell配置文件,還可以寫一個service文件實現自動運行。
例如:使用service的方式實現
[Unit]
Description=Restore iptables rules
After=network.target
[Service]
Type=oneshot
ExecStart=/sbin/iptables-restore /path/to/your/iptables.rules
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
實現NAT功能
NAT是network address translation的縮寫,譯為網路地址轉換。NAT功能通常會被集成到路由器、防火牆、或獨立的NAT設備中。
例如:
一個企業的若幹主機需要訪問公網,如果每個主機都給配一個公網IP地址,那麼IP地址早就不夠用了。所以可以在這個企業搭建一個區域網,區域網內使用私網地址,他們要訪問外網就通過NAT技術將這個區域網內所有前往公網的請求通過一個公網地址發送出去,這樣就大大解決了ip地址。
私網地址:
私網地址是區域網裡面使用的地址,隨便用.私網地址的報文是沒法在公網上面傳輸的,就算接通了外網,這些數據包也是不會發送給運營商的。公網地址需要找ISP機構申請。
-
A類:10.0.0.0 到 10.255.255.255(子網掩碼:255.0.0.0 或首碼/8)
-
B類:172.16.0.0 到 172.31.255.255(子網掩碼:255.240.0.0 或首碼/12)
-
C類:192.168.0.0 到 192.168.255.255(子網掩碼:255.255.0.0 或首碼/16)
NAT根據轉換的是源地址還是目標地址,將ANT分為SNAT和DNAT;
-
SNAT:源地址會發生改變,一般用於區域網內主機通過一個公網地址來訪問外網。
-
DNAT:目標地址會發生改變,一個從互聯網發來的數據包的目標IP會被更改為區域網內的一個私有IP地址
說明:
一般區域網內某個主機訪問公網時,出去的時候會進行SNAT轉換,回來的時候會進行DNAT轉換。數據包能通過DNAT準確回來是通過連接追蹤機制實現的。簡單說就是當數據包經過SNAT或DNAT規則時,連接跟蹤系統會為這個連接創建一個條目。這個條目會記錄數據包的原始地址和埠以及轉換後的地址和埠。
例如:
某個區域網內,有一個公網IP是15.20.64.41。某個主機需要訪問公網,就會將數據包交給這個公網IP地址進行處理,此時源IP地址就會變為這個公網ip地址,這就是SNAT。回來的時候,互連網上的指定服務將數據範圍到這個公網地址後,根據連接追蹤機制把數據交給指定的主機。這個時候目標地址會發生變化,這就是DNAT。
除了SNAT和DNAT外,還有種叫作PNAT,也叫做PAT。PNAT(或PAT)通常被看作是SNAT的一個特定形式或變種,其特點不僅在於將內部IP地址轉換為公網IP地址,還包括同時更改源埠號。這種技術的主要應用場景是當公網IP地址資源有限,但需要讓多個內部設備同時訪問互聯網時。
在使用PNAT/PAT時,外部設備看到的源地址是NAT設備的公網IP地址和一個由NAT設備分配的埠號。這樣,即使多個內部設備共用同一個公網IP地址,由於它們有不同的埠號,返回的流量依然可以被正確地路由到相應的內部設備。
iptables實現NAT實際上是通過iptables預設的 nat這個表來實現的,在數據出區或者進來的時候對數據報文進行處理。 在使用nat表來實現NAT技術的時候,-j 指定的處理動作和流量匹配時有所不同,一般常用的三種策略是:
-
DNAT:目標地址轉換
-
SNAT:源地址轉換
-
MASQUERADE:地址偽裝,這是SNAT的一種特殊形式,特別適用於動態IP地址,它會自動處理地址更改。MASQUERADE也可以進行埠轉換,從而允許多個內部設備共用單一公網IP地址。
SNAT實現
# 表示訪問的地址只要不是內網地址就使用snat的方式將請求報文源地址替換為to-source指定的地址
iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNet -j SNAT --to-source ExtIP
例如:區域網中10.0.0.0/24網段主機,只要訪問的不是10.0.0/24這個網段,就將請求報文源地址替換為172.18.1.6-172.18.1.9
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 ! –d 10.0.0.0/24 -j SNAT --to-source 172.18.1.6-172.18.1.9
如果公網IP不固定的話,要通過這種方法:
# MASQUERADE會動態的將源地址轉換為可用的IP地址
iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNet -j MASQUERADE
例如:192.168.0.0/16網段的主機訪問外網時,將192.168.0.0/16網段的請求報文源地址都更改為eth0網卡上的公網地址
ptables -t nat -A POSTROUTING -s 192.168.0.0/16 -o eth0 -j MASQUERADE
DNAT實現
iptables -t nat -A PREROUTING -d ExtIP -p tcp|udp --dport PORT -j DNAT --to-destination InterSeverIP[:PORT]
例如:如果本機的公網地址是10.0.0.100,外網的請求報文訪問10.0.0.100:80埠時,就將請求報文的目標地址改為192.168.1.100:80
iptables -t nat -I PREROUTING -d 10.0.0.100 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80
PNAT實現
例如:外網用戶要訪問內網的http服務請求的埠是80,而內網的httpd服務工作在非標準的埠8080上, 此時內網的http伺服器就需要將發送給本機80埠的數據報文重新重定向至本機的8080埠
# 法一
iptables -t nat -I PREROUTING -d 10.0.0.100 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:8080
# 法二
# REDIRECT,是NAT表的 target,通過改變目標IP和埠,將接受的包轉發至同一個主機的不同埠,可用於PREROUTING OUTPUT鏈
iptables -t nat -A PREROUTING -d 172.16.100.10 -p tcp --dport 80 -j REDIRECT --to-ports 8080
自定義規則鏈
netfilter為它的五個鉤子提供了預設的鏈,這些鏈和鉤子同名。除了netfilter提供的五個預設鏈,我們還可以自定義一些規則鏈。但是自定義鏈並不能直接使用,而是需要被預設鏈引用才能夠使用。
創建自定義鏈
(1)使用 -N 選項可以創建自定義鏈
iptables -t 表 -N 需要定義的鏈名
例如:創建一個叫做IN_WEB的自定義鏈
iptables -t filter -N IN_WEB
(2)給這個自定義鏈定義隊則
例如:實現別的主機不能ping通本機
iptables -t filter -I IN_WEB -p icmp --icmp-type 8/0 -j REJECT
(3)通過 -j 參數來在預設的規則鏈種引入自定義的規則鏈
例如:
iptables -t filter -I INPUT -j IN_WEB
刪除自定義鏈
通過 -X 參數可以刪除定義的自定義鏈,但是這個自定義鏈需要沒有被引用以及自定義鏈中沒有任何規則。
(1)清空自定義鏈規則
iptables -F <自定義鏈名稱>
(2)將預設鏈種對自定義鏈的引用刪除,刪除預設鏈中的預設規則就行了
(3)通過 -X 參數來刪除自定義鏈
iptables -X <自定義鏈名稱>