nftables 链与表管理实战:服务器防火墙规则编写与验证

nftables 链与表结构

这篇指南帮助你掌握 nftables 的表(table,按协议划分的规则容器)、链(chain,规则的有序集合)与规则(rule,匹配条件加动作的条目)三层管理方式,并学会编写、加载、验证一套服务器防火墙规则。对运行在 [VPS](https://cn.hostease.com/vps/)(Virtual Private Server,[虚拟专用服务器](https://cn.hostease.com/vps/))或[独立服务器](https://cn.hostease.com/dedicated-server/)上的业务来说,防火墙是暴露在公网的第一道防线,配置错了可能直接导致业务不可达或服务器失守,掌握能验证、能回滚的写法比背几条命令更重要。

nftables 是取代 iptables 的下一代 Linux 内核防火墙框架,它的核心设计是”表-链-规则”三级结构:表按地址族(family)划分,链决定数据包的处理阶段,规则按从上到下的顺序匹配,命中即执行 accept(接受)、drop(丢弃)等动作。相比 iptables 把规则分散在多张内置表里,nftables 的层级更清晰、脚本化更强。如果你已有 iptables 习惯,可以对照 MySQL 慢查询分析里”先看执行计划再改 SQL”的思路,先理解数据包会经过哪些链,再动手写规则。

一、表与链的创建和管理

创建一张表需要指定地址族与表名。地址族决定这张表处理哪种数据包:inet 同时覆盖 IPv4 和 IPv6,ip 只处理 IPv4,ip6 只处理 IPv6,netdev 用于网卡入口。日常服务器建议优先用 inet,避免 IPv4 与 IPv6 各写一套。

nft add table inet filter
nft list tables
nft list table inet filter

上面第一条命令创建名为 filter 的表,第二条列出所有表,第三条查看表内结构。表名可自定义,但建议保持语义清晰,比如 filter 放过滤规则、nat 放地址转换规则,互不混用。

链分两种:基链(base chain)和普通链。基链需要绑定钩子(hook,数据包在内核中经过的特定处理点,如 input、forward、output)与策略(policy),是数据包真正会流经的链;普通链只作为跳转目标,帮助把复杂规则拆成可复用的片段。创建一条绑定到 input 钩子的基链示例如下:

nft add chain inet filter input '{ type filter hook input priority 0; policy accept; }'

这里 type filter 表示过滤型链,hook input 表示处理进入本机的数据包,priority 0 表示在同类钩子中的执行顺序,policy accept 是链内没有任何规则命中时的默认动作。优先级数值越小越先执行,多个钩子重叠时要留意这一点,避免规则被其他链的 drop 抢先。

二、规则的编写与顺序

规则由匹配条件与动作组成,nft 命令把规则追加到链尾,规则按自上而下的顺序匹配,命中的第一条决定结果。下面为 input 链添加一条放行 22 端口(SSH)的规则:

nft add rule inet filter input tcp dport 22 accept

这条规则匹配 TCP 目的端口 22 并放行。若想插入到链的特定位置而非末尾,用 insert 或指定 handle(句柄,规则的唯一编号)插入。规则的顺序非常关键:如果先写了一条 drop all 的默认拒绝规则,再往链尾追加放行 22 的规则,放行永远不会生效,因为数据包在到达放行规则前已经被丢弃。

多条件组合可以用逻辑运算符。下面这条规则放行来自内网网段对 3306 端口的访问,其余来源一律由后面的默认策略处理:

nft add rule inet filter input ip saddr 192.168.1.0/24 tcp dport 3306 accept

ip saddr 指定源地址,192.168.1.0/24 是内网网段示例。实际网段请按你自己的网络规划填写。规则里可以组合源地址、目的地址、端口、协议、接口(interface,网卡名称)等多个维度,例如 iifname 限制入口网卡、ct state 匹配连接状态,让放行范围精确到最小权限。

nftables 规则集匹配流程

端口变化频繁或要统一管理放行清单时,可以用命名集合(named set)把多个地址或端口放进一个集合,规则里直接引用集合名,后续只需改集合而不用改每条规则。这个思路与 Nginx 限流配置里把白名单抽象成独立配置的做法一致,都是把”经常变的清单”与”规则本身”解耦,降低误改风险。

三、NAT 与状态跟踪

除了过滤,nftables 也承担 NAT(Network Address Translation,网络地址转换)工作。NAT 链通常放在名为 nat 的表中,绑定 postrouting 或 prerouting 钩子。典型的出站源地址转换(把内网地址转成出口公网地址)写法如下:

nft add table ip nat
nft add chain ip nat postrouting '{ type nat hook postrouting priority 100; }'
nft add rule ip nat postrouting ip saddr 10.0.0.0/24 masquerade

masquerade 适合出口地址动态变化的场景,它会自动取当前出接口地址作为转换后的源地址。若出口地址固定,可以用 snat 指定具体地址。这里 10.0.0.0/24 是内网网段示例,实际按你的网络填写。注意 NAT 与过滤是不同的表,改 NAT 不会影响过滤链,两者配合时先理清数据包流向再写,避免出现”过滤放行了但 NAT 没配”或反之的漏网情况。

状态跟踪(stateful tracking)是防火墙高效放行的关键。通过 ct state 可以只对”新建连接”做严格判断,已建立或相关的回包直接放行,避免为每个回包写单独规则。典型写法是在 input 链开头放行 established 与 related 状态,只对 new 状态做业务规则匹配。这个”先放行既有连接、再管新建连接”的顺序建议始终放在链的最前面,具体可参考 WireGuard 多跳中继配置中关于隧道数据流量方向与状态判断的对照理解。

四、规则的持久化与加载

nft 命令的修改只在内存中生效,重启后丢失。要让规则在开机时自动恢复,需要把当前规则集导出成脚本并配置开机加载。查看完整规则集并保存:

nft list ruleset > /etc/nftables.conf
systemctl enable nftables
systemctl restart nftables

/etc/nftables.conf 是 nftables 服务的默认加载文件,systemd(Linux 的服务管理框架)会按该文件在开机时重建规则。改规则的正确流程是:先编辑脚本文件,再用 nft -f 语法检查,最后用 systemctl reload 或重启服务加载,避免直接敲命令导致脚本与实际状态脱节。

保存前务必确认脚本语法无误。可以用 nft -c -f /etc/nftables.conf 做一次只检查不生效的语法校验(-c 表示 check)。若加载后发现自己被锁在服务器外,多半是规则顺序或默认策略把 SSH 也拒绝了,所以任何防火墙改动都要保留一个可回滚的手段,具体排错方法见下一节。

五、规则验证与安全回滚

防火墙上线前必须验证,否则一次手误就可能让整个业务不可达。最稳妥的做法是”脚本化 + 定时回滚”:把规则写进脚本,加载前记录当前规则集哈希,加载后启动一个延迟定时器,若在倒计时内未手动确认,就自动恢复旧规则。下面是一个可选的回滚辅助思路:

# 备份当前规则
nft list ruleset > /root/fw_backup.conf
 # 加载新规则
nft -f /etc/nftables.conf
 # 倒计时后若未确认则恢复
sleep 60 && nft -f /root/fw_backup.conf

上面的 60 秒属于示例值,可按你的排障速度调整。实际更推荐的做法是开两个 SSH 会话:一个会话加载新规则,另一个会话保持心跳连接,一旦发现断开立即用备份恢复。恢复前先用 nft list ruleset 对比规则是否与预期一致,确认是新规则导致的问题再回滚,避免误把原本就存在的问题归咎于本次改动。

nftables 规则验证与回滚

排查连通性问题时,先分清是规则放行、路由还是监听问题。用 nft list chain inet filter input 查看链内规则与命中计数,观察数据包是否被规则 drop。若计数不增长,说明数据包根本没到这条链,应转向查路由或服务监听。这个”先定位数据包到没到、再判断被谁处理”的分步排查思路,与 Certbot SSL(Secure Sockets Layer,安全套接层)证书排查里先验证证书链再续期的做法同理,都是先确认基础链路正常,再向下定位。

如果服务器需要通过监控持续观察端口与流量变化,可以把关键端口的状态接入告警体系,部署方法可参考 Grafana 服务器部署实战。这样防火墙规则变更后,业务指标是否有异常波动一目了然。需要同时管理多台服务器的防火墙基线时,还可参考 Redis 持久化与恢复中对配置快照与恢复点的管理思路,为每台机器的规则集保留可追溯的版本。

总结

nftables 防火墙管理的核心是把握三层结构:表按协议分域、链按处理阶段组织、规则按顺序匹配。写规则要遵循”先放行既有连接、再管理新建连接、默认策略兜底”的顺序,改动前备份、改动后验证、必要时回滚。对 Hostease 环境上的服务器,建议把规则全部脚本化并通过服务管理,配合定时备份与连通性验证,让防火墙既能挡住风险,又不会在维护时把自己关在门外。只要坚持”先验证再生效、留好回滚”这两条,nftables 完全可以安全地承担服务器的网络边界防护。

发表评论