nftables 快速入門:表、鏈、規則和常用操作

整理 nftables 的入門思路:理解 table、chain、rule 的關係,並透過 IP、MAC、連接埠匹配、流量統計、限速和規則刪除等常用命令快速上手。

nftables 是 Linux 上常用的封包過濾和防火牆規則管理工具。如果只是做設備連線控制、流量統計、連接埠匹配或簡單限速,不需要一開始就把完整規則體系全部學完,先理解三個概念就夠了:

  • table:規則的容器。
  • chain:規則執行的位置,通常會掛到某個 hook 上。
  • rule:真正的匹配條件和動作。

下面整理一套最小可用的入門流程,適合先在測試環境裡做實驗。

基礎結構

先準備幾個變數,後面的命令會重複使用:

1
2
3
4
5
table=customtable
chain=custom_control
target=drop
ip=192.168.18.251
mac=00:00:01:02:03:04

建立一個同時支援 IPv4 和 IPv6 的 inet table:

1
nft add table inet $table

再建立一條掛在 forward 階段的 chain:

1
nft add chain inet $table $chain { type filter hook forward priority 0\; }

這裡的 type filter 表示做過濾規則,hook forward 表示處理經過轉發的封包。

常見匹配方式

按來源 IP 匹配,通常可以理解為設備上傳方向:

1
nft add rule inet $table $chain ip saddr $ip $target

按目標 IP 匹配,通常可以理解為設備下載方向:

1
nft add rule inet $table $chain ip daddr $ip $target

按 MAC 位址匹配時,可以用 ether saddr 控制上行:

1
nft add rule inet $table $chain ether saddr $mac $target

需要注意的是,在經過橋接、轉發或位址轉換的網路裡,下行封包未必能可靠用目標 MAC 過濾。實際做設備連線控制時,優先從 ether saddr 或 IP 規則開始驗證。

匹配連接埠時,可以同時覆蓋 TCP 和 UDP:

1
nft add rule inet $table $chain { tcp, udp } dport 22 $target

如果要匹配連接埠範圍,可以使用比較表達式:

1
nft add rule inet $table $chain tcp dport \>= 1024 $target

統計單個設備流量

如果只是想統計某個 IP 的上下行流量,可以用 counter return。這樣命中後記錄計數並返回,後面還有其他統計規則時,能減少繼續匹配的開銷。

1
2
nft add rule inet $table $chain ip saddr $ip counter return
nft add rule inet $table $chain ip daddr $ip counter return

查看統計結果:

1
nft list chain inet $table $chain

如果需要看到每條規則的 handle,加上 -a

1
nft -a list chain inet $table $chain

handle 很重要,因為 nftables 刪除單條規則時通常要靠它定位。

簡單限速

限速可以用 limit rate over。例如按 MAC 位址限制超過指定速率的流量:

1
2
3
4
rate=10
unit=mbytes

nft add rule inet $table $chain ether saddr $mac limit rate over $rate $unit/second drop

這裡的 mbyteskbytes 可以按日常理解的 M、K 來看,不需要再手動做 8 倍換算。實際使用時建議先用較寬鬆的值測試,確認命中方向和效果後再收緊。

刪除和清理規則

先查看帶 handle 的規則:

1
nft -a list chain inet $table $chain

再按 handle 刪除某條規則:

1
nft delete rule inet $table $chain handle <handle>

清空某條 chain:

1
nft flush chain inet $table $chain

刪除 chain:

1
nft delete chain inet $table $chain

刪除整個 table:

1
nft delete table inet $table

日常除錯時,建議先只清理自己建立的 table,不要直接改系統或其他服務自動生成的 table。這樣即使規則寫錯,也更容易回滾。

使用建議

使用 nftables 時,可以優先自己建立獨立的 table 和 chain。這樣做有兩個好處:

  1. 不容易和系統已有規則混在一起。
  2. 除錯、清空和刪除都更安全。

另外,規則寫完後一定要用 nft list chain 看實際命中情況。尤其是 MAC、介面、連接埠和限速規則,不同設備、橋接方式和系統版本下表現可能不同,先小範圍測試比一次性寫複雜規則更穩。

參考

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