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 设计