學習 nftables 時,容易一開始就陷入命令細節:怎麼新增規則、怎麼刪除 handle、怎麼寫連接埠匹配。命令當然重要,但如果先把框架概念理清楚,後面讀規則、排查問題和設計規則集都會輕鬆很多。
可以把 nftables 理解成一套分層結構:
table負責隔離規則空間。family決定規則處理哪類網路協定。chain決定規則在什麼階段執行。rule負責具體匹配和動作。set、map、verdict map用來減少重複規則,讓規則集更易維護。
下面按概念逐層說明。
table:規則的命名空間
table 是 nftables 裡最外層的規則容器。不同 table 之間相互隔離,因此常見做法是把一組相關規則放進同一個 table。
例如,你可以把過濾規則、NAT 規則或自訂測試規則分開放。這樣做的好處是邊界清楚:除錯時知道自己在改哪一組規則,清理時也不容易誤刪無關內容。
table 本身不會直接處理封包。真正參與封包處理的是 table 裡面的 chain 和 rule。
family:規則面對哪類協定
建立 table 時需要選擇 family。它決定這張表裡的規則適用於哪類封包。
常見 family 可以這樣理解:
ip:只處理 IPv4。ip6:只處理 IPv6。inet:同時處理 IPv4 和 IPv6。arp:處理 ARP。bridge:處理橋接層流量。netdev:更靠近網路設備入口,適合較早階段處理流量。
日常寫普通防火牆規則時,inet 很常用。它可以把 IPv4 和 IPv6 規則放在同一個 table 裡,避免維護兩套結構相似的規則。
chain:規則執行的位置
chain 是 rule 的列表。封包進入某個 hook 後,會按順序經過 chain 裡的規則。
chain 大致可以分為兩類:
- 基本 chain:掛到核心網路路徑的某個 hook 上,會被封包流程主動呼叫。
- 常規 chain:不直接掛 hook,需要被其他規則跳轉呼叫。
基本 chain 通常會指定幾個關鍵屬性:
type:這條 chain 的用途,例如filter、nat、route。hook:掛在哪個處理階段,例如prerouting、input、forward、output、postrouting。priority:同一個 hook 上有多條 chain 時,誰先執行。policy:沒有規則匹配時的預設動作,常見是accept或drop。
理解 chain 的關鍵是:規則不是「隨便寫在哪裡都能生效」。同一條規則放在 input、forward 或 output,含義完全不同。
rule:匹配條件加動作
rule 是 nftables 裡真正做判斷的地方。它通常由兩部分組成:
- 匹配條件:例如來源 IP、目標 IP、協定、連接埠、介面、連線狀態。
- 動作:例如
accept、drop、reject、counter、jump、return。
規則會按順序求值。封包命中某條會終止流程的動作後,就不會繼續執行後面的規則。沒有命中時,則繼續往下走,直到 chain 結束或觸發預設策略。
這也是為什麼規則順序很重要:更具體的規則通常要放在更寬泛的規則前面,否則可能永遠沒有機會被執行。
set:把一組值放在一起
如果有很多 IP、連接埠或介面需要匹配,直接寫多條規則會很難維護。set 用來把一組同類型的值集中管理。
例如,一組可信 IP、一組禁止存取的連接埠、一組需要限速的位址,都可以放進 set。規則只需要判斷某個值是否屬於這個 set。
set 的好處是:
- 規則數量更少。
- 可讀性更好。
- 後續增刪元素更方便。
當規則裡出現大量重複條件時,通常就該考慮用 set。
map:把匹配值映射成結果
map 可以理解成「查表」。它根據一個輸入值返回一個結果。
例如,不同連接埠映射到不同標記,不同位址映射到不同處理參數,都可以透過 map 表達。相比寫多條 if/else 式規則,map 更集中,也更容易維護。
set 關心的是「是否在集合裡」,map 關心的是「這個值對應什麼結果」。
verdict map:把匹配值映射成動作
verdict map 是 map 的一個重要用法:它把匹配值映射成 verdict,也就是規則動作。
例如,不同 IP 段可以對應 accept、drop 或跳轉到不同 chain。這樣可以把很多分支判斷壓縮到一個結構裡。
當規則集開始變複雜時,verdict map 很有用。它能減少重複規則,也能把策略表達得更像一張表,而不是一長串判斷語句。
從概念看規則設計
設計 nftables 規則時,可以按這個順序思考:
- 先確定規則屬於哪個
family。 - 再決定放進哪個
table。 - 然後選擇合適的
hook和chain。 - 最後編寫具體
rule。 - 如果重複條件很多,再引入
set、map或verdict map。
這樣寫出來的規則會更容易維護,也更容易排錯。
小結
nftables 的概念並不複雜,但層級很重要:
- table 管規則邊界。
- family 管協定範圍。
- chain 管執行位置。
- rule 管匹配和動作。
- set、map、verdict map 管複雜度。
先理解這些概念,再去看具體命令,會比直接背命令更穩。尤其是在規則集變多以後,概念清楚能幫助你判斷:問題到底出在協定範圍、執行階段、規則順序,還是匹配條件本身。