理解 nftables 框架:表、鏈、規則和集合

從概念層面梳理 nftables 框架:table、family、chain、rule、set、map 和 verdict map 分別解決什麼問題,以及它們如何組合成可維護的防火牆規則。

學習 nftables 時,容易一開始就陷入命令細節:怎麼新增規則、怎麼刪除 handle、怎麼寫連接埠匹配。命令當然重要,但如果先把框架概念理清楚,後面讀規則、排查問題和設計規則集都會輕鬆很多。

可以把 nftables 理解成一套分層結構:

  • table 負責隔離規則空間。
  • family 決定規則處理哪類網路協定。
  • chain 決定規則在什麼階段執行。
  • rule 負責具體匹配和動作。
  • setmapverdict 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 大致可以分為兩類:

  1. 基本 chain:掛到核心網路路徑的某個 hook 上,會被封包流程主動呼叫。
  2. 常規 chain:不直接掛 hook,需要被其他規則跳轉呼叫。

基本 chain 通常會指定幾個關鍵屬性:

  • type:這條 chain 的用途,例如 filternatroute
  • hook:掛在哪個處理階段,例如 preroutinginputforwardoutputpostrouting
  • priority:同一個 hook 上有多條 chain 時,誰先執行。
  • policy:沒有規則匹配時的預設動作,常見是 acceptdrop

理解 chain 的關鍵是:規則不是「隨便寫在哪裡都能生效」。同一條規則放在 inputforwardoutput,含義完全不同。

rule:匹配條件加動作

rule 是 nftables 裡真正做判斷的地方。它通常由兩部分組成:

  • 匹配條件:例如來源 IP、目標 IP、協定、連接埠、介面、連線狀態。
  • 動作:例如 acceptdroprejectcounterjumpreturn

規則會按順序求值。封包命中某條會終止流程的動作後,就不會繼續執行後面的規則。沒有命中時,則繼續往下走,直到 chain 結束或觸發預設策略。

這也是為什麼規則順序很重要:更具體的規則通常要放在更寬泛的規則前面,否則可能永遠沒有機會被執行。

set:把一組值放在一起

如果有很多 IP、連接埠或介面需要匹配,直接寫多條規則會很難維護。set 用來把一組同類型的值集中管理。

例如,一組可信 IP、一組禁止存取的連接埠、一組需要限速的位址,都可以放進 set。規則只需要判斷某個值是否屬於這個 set。

set 的好處是:

  • 規則數量更少。
  • 可讀性更好。
  • 後續增刪元素更方便。

當規則裡出現大量重複條件時,通常就該考慮用 set。

map:把匹配值映射成結果

map 可以理解成「查表」。它根據一個輸入值返回一個結果。

例如,不同連接埠映射到不同標記,不同位址映射到不同處理參數,都可以透過 map 表達。相比寫多條 if/else 式規則,map 更集中,也更容易維護。

set 關心的是「是否在集合裡」,map 關心的是「這個值對應什麼結果」。

verdict map:把匹配值映射成動作

verdict map 是 map 的一個重要用法:它把匹配值映射成 verdict,也就是規則動作。

例如,不同 IP 段可以對應 acceptdrop 或跳轉到不同 chain。這樣可以把很多分支判斷壓縮到一個結構裡。

當規則集開始變複雜時,verdict map 很有用。它能減少重複規則,也能把策略表達得更像一張表,而不是一長串判斷語句。

從概念看規則設計

設計 nftables 規則時,可以按這個順序思考:

  1. 先確定規則屬於哪個 family
  2. 再決定放進哪個 table
  3. 然後選擇合適的 hookchain
  4. 最後編寫具體 rule
  5. 如果重複條件很多,再引入 setmapverdict map

這樣寫出來的規則會更容易維護,也更容易排錯。

小結

nftables 的概念並不複雜,但層級很重要:

  • table 管規則邊界。
  • family 管協定範圍。
  • chain 管執行位置。
  • rule 管匹配和動作。
  • set、map、verdict map 管複雜度。

先理解這些概念,再去看具體命令,會比直接背命令更穩。尤其是在規則集變多以後,概念清楚能幫助你判斷:問題到底出在協定範圍、執行階段、規則順序,還是匹配條件本身。

參考

记录并分享
使用 Hugo 建立
主題 StackJimmy 設計