iptables 的五表五鏈
概述
iptables 是一個配置 Linux 內核防火牆的命令行工具,它基於內核的包過濾框架(packet filtering framework) netfilter, 主要用於管理數據包過濾和 NAT 規則。
iptables
與協議棧內有包過濾功能的 hook 交 互來完成工作。這些內核 hook 構成了 netfilter
框架。每個進入網絡系統的包(接收或發送)在經過協議棧時都會觸發這些 hook, 程序可以通過註冊 hook 函數的方式在一些關鍵路徑上處理網絡流量。iptables
相關的內核模塊在這些 hook 點註冊了處理函數,因此可以通過配置 iptables
規則來使得網絡流量符合防火牆規則。
理解
iptables
是學習Docker
,Kubernetes
等開源項目中網絡功能實現的基礎。
規則
規則
就是網絡管理員預定義的條件,一般的定義爲 如果數據包頭符合當前條件,處理這個數據包,反之執行下一個判斷條件, 規則
存儲在內核空間的過濾表中,這些規則分別指定了 源地址
、目的地址
、傳輸協議
(如 TCP、UDP、ICMP)和 服務類型
(如 HTTP、FTP 和 SMTP)等, 當數據包與 規則
匹配時,內核會執行具體的 行爲
。
配置防火牆的主要工作就是添加、修改和刪除規則。
行爲
5 鏈
鏈
是數據包傳播的路徑,每一個 鏈
中可以有 N 個 規則
(N>= 0)。當數據包到達一個 鏈
時,iptables
就會從鏈中第一個規則開始檢測, 如果數據包滿足規則所定義的條件,系統會執行具體的 行爲
,否則 iptables
繼續檢查下一個規則。 如果數據包不符合鏈中任一個規則,iptables
就會根據該鏈預先定義的默認策略來處理數據包。
5 表
表有 N 個鏈,鏈有 N 個規則。
大部分場景僅需使用 Filter 表 和 NAT 表。
Raw 表
Raw
表用於在 連接跟蹤、NAT 和路由表處理之前 對數據包進行處理,包含 2 種內置鏈:
-
PREROUTING
-
OUTPUT
因爲優先級最高,所以如果使用了 Raw
表,那麼在 Raw
表處理完後, 將跳過 NAT
表和 ip_conntrack
處理, 也就是避免了 連接跟蹤、NAT 和路由表前置 處理。
Filter 表
Filter
是 iptables
的默認表,用於過濾數據包,如果沒有定義表的情況下將使用 Filter
表,包含 3 種內置鏈:
-
INPUT
-
OUTPUT
-
FORWARD
在 Filter
表中只允許對數據包進行接受,丟棄的操作,而無法對數據包進行更改。
NAT 表
NAT
用於實現網絡地址轉換,包含 3 種內置鏈:
-
PREROUTING
-
POSTROUTING
-
OUTPUT
Mangle 表
Mangle
用於對指定數據包報頭進行修改、標記或重定向,包含 5 種內置鏈:
-
INPUT
-
OUTPUT
-
FORWARD
-
PREROUTING
-
POSTROUTING
Security 表
Security
用於給包打上 SELinux 標記,以此影響 SELinux 或其他可以解讀 SELinux 安全上下文的系統處理包的行爲。這些標記可以基於單個包,也可以基於連接。
表和鏈關係圖
表和鏈關係圖
表的檢測優先級
Raw -> Mangle -> Nat -> Filter
任何一個數據包必然經過 5 個鏈中的其中一個。
-
• 一個數據包進入網卡時,首先進入
PREROUTING
鏈,內核根據數據包目的 IP 判斷是否需要轉發 -
• 如果數據包是進入本機的,它就會沿着圖向下移動,到達
INPUT
鏈,數據包到了 INPUT 鏈後,任何進程都會收到它,本機上程序可以發送數據包,這些數據包會經過OUTPUT
鏈,然後到達POSTROUTING
鏈輸出 -
• 如果數據包是轉發出去的,且內核允許轉發,數據包會經過
FORWARD
鏈,然後到達POSTROUTING
鏈輸出
常用命令
查看類
# 查看所有防火牆規則
$ iptables --list
# 示例輸出如下
Chain DOCKER (8 references)
target prot opt source destination
ACCEPT tcp -- anywhere 172.27.0.2 tcp dpt:10010
ACCEPT tcp -- anywhere 172.22.0.2 tcp dpt:http
ACCEPT tcp -- anywhere 172.29.0.4 tcp dpt:memcached
ACCEPT tcp -- anywhere 172.17.0.2 tcp dpt:redis
ACCEPT tcp -- anywhere 172.17.0.2 tcp dpt:nginx
ACCEPT tcp -- anywhere 172.17.0.4 tcp dpt:8080
ACCEPT tcp -- anywhere 172.17.0.5 tcp dpt:mysql
ACCEPT tcp -- anywhere 172.17.0.5 tcp dpt:http
# 查看 mangle 表規則
$ iptables -t mangle --list
# 查看 nat 表規則
$ iptables -t nat --list
操作類
# 查看說明
$ iptables --help
# 查看命令
iptables -L:查看規則鏈
# 規則管理命令
iptables -A:在規則鏈的末尾加入新規則
iptables -D:刪除某個規則
iptables -I:在規則鏈的頭部加入新規則
iptables -R:替換規則鏈中的規則
# 鏈管理命令
iptables -F:清空規則鏈
iptables -Z:清空規則鏈中的數據包計算器和字節計數器
iptables -N:創建新的用戶自定義規則鏈
iptables -P:設置規則鏈中的默認策略
# 通用匹配參數
-t
對指定的表 table 進行操作
如果不指定此選項,默認的是 filter 表
-p 協議
指定規則的協議,如 tcp, udp, icmp 等,可以使用all來指定所有協議
如果不指定 -p 參數,默認的是 all 值
-s 源地址
指定數據包的源地址
參數可以使IP地址、網絡地址、主機名
例如:-s 192.168.1.101 指定IP地址
例如:-s 192.168.1.10/24 指定網絡地址
-d 目的地址
指定數據包的目的地址,規則和 -s 類似
-j 執行目標
指定規則匹配時如何處理數據包
可能的值是ACCEPT, DROP, QUEUE, RETURN 等
-i 輸入接口
指定要處理來自哪個接口的數據包,這些數據包將進入 INPUT, FORWARD, PREROUTE 鏈
例如:-i eth0指定了要處理經由eth0進入的數據包
如果不指定 -i參數,那麼將處理進入所有接口的數據包
如果指定 ! -i eth0,那麼將處理所有經由eth0以外的接口進入的數據包
如果指定 -i eth+,那麼將處理所有經由eth開頭的接口進入的數據包
-o 輸出
指定了數據包由哪個接口輸出,這些數據包將進入 FORWARD, OUTPUT, POSTROUTING鏈
如果不指定-o選項,那麼所有接口都可以作爲輸出接口
如果指定 ! -o eth0,那麼將從eth0以外的接口輸出
如果指定 -i eth+,那麼將僅從eth開頭的接口輸出
# 擴展參數
-sport 源端口
針對 -p tcp 或者 -p udp,默認情況下,將匹配所有端口
可以指定端口號或者端口名稱、端口範圍,例如 –sport 22, –sport ssh,–sport 22:100
從性能上講,使用端口號更好, /etc/services 文件描述了映射關係
-dport 目的端口
規則和 –sport 類似
-tcp-flags TCP 標誌
針對 -p tcp
可以指定由逗號分隔的多個參數
取值範圍:SYN, ACK, FIN, RST, URG, PSH, ALL, NONE
-icmp-type ICMP 標誌
針對 -p icmp
icmp-type 0 表示 Echo Reply
icmp-type 8 表示 Echo
命令選項輸入順序
iptables -t 表名 <-A/I/D/R> 規則鏈名 [規則號] <-i/o 網卡名> -p 協議名 <-s 源IP/源子網> --sport 源端口 <-d 目標IP/目標子網> --dport 目標端口 -j 動作
示例
以下命令在生產環境中謹慎使用。
查看已添加的 iptables 規則
$ iptables -L -n -v
Chain INPUT (policy DROP 48106 packets, 2690K bytes)
pkts bytes target prot opt in out source destination
5075 589K ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
191K 90M ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
1499K 133M ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
4364K 6351M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
6256 327K ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 3382K packets, 1819M bytes)
pkts bytes target prot opt in out source destination
5075 589K ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0
清空當前的所有規則和計數
$ iptables -F # 清空所有的防火牆規則
$ iptables -X # 刪除用戶自定義的空鏈
$ iptables -Z # 清空計數
設置默認規則
$ iptables -P INPUT DROP # 配置默認的不讓進
$ iptables -P FORWARD DROP # 默認的不允許轉發
$ iptables -P OUTPUT ACCEPT # 默認的可以出去
開放指定端口
$ iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT # 允許本地迴環接口(即運行本機訪問本機)
$ iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # 允許已建立的或相關連的通行
$ iptables -A OUTPUT -j ACCEPT # 允許所有本機向外的訪問
$ iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 允許訪問22端口
$ iptables -A INPUT -p tcp --dport 80 -j ACCEPT # 允許訪問80端口
$ iptables -A INPUT -p tcp --dport 21 -j ACCEPT # 允許ftp服務的21端口
$ iptables -A INPUT -p tcp --dport 20 -j ACCEPT # 允許FTP服務的20端口
$ iptables -A INPUT -j reject # 禁止其他未允許的規則訪問
$ iptables -A FORWARD -j REJECT # 禁止其他未允許的規則訪問
白名單
$ iptables -A INPUT -p all -s 192.168.1.0/24 -j ACCEPT # 允許機房內網機器可以訪問
$ iptables -A INPUT -p all -s 192.168.140.0/24 -j ACCEPT # 允許機房內網機器可以訪問
$ iptables -A INPUT -p tcp -s 183.121.3.7 --dport 3380 -j ACCEPT # 允許 183.121.3.7 訪問本機的 3380 端口
黑名單
iptables -I INPUT -s 123.45.6.7 -j DROP # 屏蔽單個 IP
iptables -I INPUT -s 123.0.0.0/8 -j DROP # 屏蔽 IP 網段 從 123.0.0.1 到 123.255.255.254
iptables -I INPUT -s 124.45.0.0/16 -j DROP # 屏蔽 IP 網段 從 123.45.0.1 到 123.45.255.254
iptables -I INPUT -s 123.45.6.0/24 -j DROP # 屏蔽 IP 網段 從 123.45.6.1 到 123.45.6.254
防止 SYN 洪水攻擊
$ iptables -A INPUT -p tcp --syn -m limit --limit 5/second -j ACCEPT
小結
撰寫本文過程中,筆者發現中文內容幾乎說的都是 四表五鏈
,不知是作者刻意跳過 Security
表,還是抄襲導致的同質化太嚴重。 雖然 Security
表不是常用功能,但是我們不能忽略其存在。
Reference
-
Traversing of tables and chains[1]
-
iptables(8) - Linux man page[2]
-
iptables[3]
-
iptables 詳解 [4]
-
iptables command[5]
-
深入理解 iptables 和 netfilter 架構 [6]
引用鏈接
[1]
Traversing of tables and chains: https://www.frozentux.net/iptables-tutorial/iptables-tutorial.html#TRAVERSINGOFTABLES
[2]
iptables(8) - Linux man page: https://linux.die.net/man/8/iptables
[3]
iptables: https://wiki.archlinuxcn.org/wiki/Iptables
[4]
iptables 詳解: https://lixiangyun.gitbook.io/iptables_doc_zh_cn/
[5]
iptables command: https://wangchujiang.com/linux-command/c/iptables.html
[6]
深入理解 iptables 和 netfilter 架構: https://arthurchiao.art/blog/deep-dive-into-iptables-and-netfilter-arch-zh/
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/D0FqiY5pPE9pJ-6AFMbZWQ