90%人沒理清的 iptables 核心:七表五鏈實戰指北
引言
今天就圍繞這個問題,來探討下,這個問題能完全回答上來的沒有幾個。工作中用到的不多,但是這是每一個 Linux 工程師都需要知道的底層知識。
開始
在 Kubernetes 集群中,當某個節點突然無法轉發流量時,你可能會在日志中看到 iptables rules conflict 的報錯——這背后隱藏的是 Linux 網絡層最核心的流量控制機制:iptables。作為 Linux 內核級防火墻工具,iptables 通過 七張表(Tables) 和 五條鏈(Chains) 的組合,實現了從網絡層到應用層的精細化流量控制。本文將從底層原理、核心架構、實戰命令三個維度,拆解 iptables 的設計哲學。
一、先導知識:數據包的“人生旅程”
當一個數據包進入Linux系統時,它會經歷多個“檢查站”,每個檢查站都有不同的決策規則。這個過程類似于快遞分揀:
1. 入境檢查(PREROUTING):判斷包裹是否要轉運(NAT)或直接派送。
2. 本地派送(INPUT):決定是否簽收(交給本機應用)。
3. 跨境運輸(FORWARD):中轉包裹到其他機器。
4. 出境準備(OUTPUT):處理本機發出的包裹。
5. 出境登記(POSTROUTING):記錄包裹最終去向。
二、七張表:不同職能的“決策部門”
注意:傳統說法中的“七表”實際是歷史版本的概念,現代Linux內核(4.x+)常用五張表:raw、filter、nat、mangle、security。此處以生產環境常用表解析。
1. raw表(原始數據裁決所)
? 職能:在連接跟蹤(conntrack)之前處理數據包,決定是否跳過狀態跟蹤。
? 應用場景:
對特定流量禁用連接跟蹤(如高并發場景優化性能)。
標記不需要NAT的流量。
# 禁用對80端口的連接跟蹤
iptables -t raw -A PREROUTING -p tcp --dport 80 -j NOTRACK
2. filter表(流量安檢門)
? 職能:決定是否允許數據包通過(ACCEPT/DROP/REJECT)。
? 核心鏈:INPUT、FORWARD、OUTPUT。
? 經典規則:
# 允許已建立的連接
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# 阻止所有入站SSH暴力破解
iptables -A INPUT -p tcp --dport 22 -m recent --name SSH --set
iptables -A INPUT -p tcp --dport 22 -m recent --name SSH --update --seconds 60 --hitcount 3 -j DROP
3. nat表(地址翻譯局)
? 職能:修改數據包的源/目標地址(SNAT/DNAT)。
? 核心鏈:PREROUTING、OUTPUT、POSTROUTING。
? 典型配置:
# 將外部訪問1.1.1.1:80轉發到內網10.0.0.2:80(DNAT)
iptables -t nat -A PREROUTING -d 1.1.1.1 -p tcp --dport 80 -j DNAT --to 10.0.0.2:80
# 內網機器通過網關上網(SNAT)
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j SNAT --to-source 2.2.2.2
4. mangle表(數據整形科)
? 職能:修改數據包頭部信息(如TTL、TOS、MARK)。
? 應用場景:
基于QoS標記流量優先級。
實現策略路由(結合iproute2)。
# 標記所有HTTP流量為優先級1
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 1
5. security表(強制安檢室)
? 職能:實現強制訪問控制(如SELinux策略)。
? 使用頻率低:多數企業依賴上層防火墻或AppArmor/SELinux。
三、五條鏈:數據包的“必經關卡”
1. PREROUTING鏈(入境登記處)
? 觸發時機:數據包進入網卡后,路由決策前。
? 常用表:raw、nat、mangle。
? 典型操作:DNAT、流量標記。
2. INPUT鏈(本地簽收臺)
? 觸發時機:數據包目標為本機進程。
? 常用表:filter、mangle。
? 經典防御:過濾惡意掃描、限制ICMP洪水攻擊。
3. FORWARD鏈(跨境中轉站)
? 觸發時機:數據包需要轉發到其他機器。
? 常用表:filter、mangle。
? 核心用途:實現Linux網關或容器網絡流量控制。
4. OUTPUT鏈(出境安檢口)
? 觸發時機:本機進程發出的數據包。
? 常用表:raw、filter、mangle、nat。
? 特殊場景:限制本機程序對外訪問(如禁止MySQL客戶端連接外網)。
5. POSTROUTING鏈(出境登記處)
? 觸發時機:數據包發送到網卡前,路由決策后。
? 常用表:nat、mangle。
? 核心操作:SNAT(源地址轉換)。
四、優先級與規則執行順序
1. 表的處理順序(從高到低)
raw → mangle → nat → filter → security
2. 鏈的執行流程
[ 數據包進入網卡 ]
│
▼
PREROUTING鏈
│
▼
路由決策(判斷去向)
│
├─目標為本機─────→ INPUT鏈 ───→ 本地應用
│
└─需要轉發─────→ FORWARD鏈 ───→ POSTROUTING鏈
│
[ 本地應用發送數據包 ]
│
▼
OUTPUT鏈
│
▼
POSTROUTING鏈
│
▼
[ 數據包離開網卡 ]
五、生產環境實戰案例
案例 1:Kubernetes 節點流量轉發異常
? 現象:Pod 跨節點通信失敗,iptables-save 顯示大量 KUBE-SVC 規則
? 根因:nf_conntrack 表滿導致丟包
? 解決方案:
# 調整 conntrack 表大小
echo 524288 > /proc/sys/net/netfilter/nf_conntrack_max
# 添加 raw 表規則繞過跟蹤(需評估安全影響)
iptables -t raw -A PREROUTING -p tcp --dport 80 -j NOTRACK
案例 2:防御 SSH 暴力破解
? 動態封禁策略:
# 使用 recent 模塊記錄攻擊者 IP
iptables -A INPUT -p tcp --dport 22 -m recent --name ssh_attack --update --seconds 3600 -j DROP
iptables -A INPUT -p tcp --dport 22 -m recent --name ssh_attack --set -j ACCEPT
六、性能優化技巧
1. 減少規則數量
? 合并同類規則,如用IP集合(ipset)替代多個-s參數:
ipset create blacklist hash:ip
ipset add blacklist 192.168.1.100
iptables -A INPUT -m set --match-set blacklist src -j DROP
2. 調整表優先級
? 高頻規則放在raw或mangle表,盡早攔截無效流量:
# 在raw表丟棄無效連接
iptables -t raw -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP
3. 關閉不需要的功能
? 停用無用的內核模塊(如nf_conntrack_ftp)以減少計算開銷:
echo 0 > /proc/sys/net/netfilter/nf_conntrack_helper
七、常見誤區與排坑指南
誤區1:“規則順序無所謂”
? 問題:iptables規則按從上到下的順序匹配。
? 反例:先ACCEPT all再DROP ssh會導致SSH未被阻斷。
? 正解:嚴格規則在前,通用規則在后。
誤區2:“DROP比REJECT更安全”
? 陷阱:DROP會靜默丟棄數據包,導致客戶端長時間等待。
? 建議:對已知惡意IP用DROP,對誤操作用戶用REJECT。
誤區3:“nat表能過濾流量”
? 真相:nat表僅用于地址轉換,過濾必須依賴filter表。
? 錯誤配置:
iptables -t nat -A POSTROUTING -s 10.0.0.5 -j DROP # 無效!
結語
當你在 Kubernetes 集群中看到 kube-proxy 生成的數千條 iptables 規則時,不必感到恐懼——這正是七表五鏈設計靈活性的體現。掌握本文內容后,你可以:
1. 精準定位生產環境中的網絡策略沖突
2. 為特定業務定制高性能流量控制規則
3. 寫出比 Kubernetes 默認實現更優雅的 CNI 插件