直接上手可用的nftables配置需先清空旧规则并选用inet协议族(同时支持IPv4/IPv6),创建表nft add table inet filter和默认drop的input链,再按顺序添加lo、ct state established/related、tcp dport 22 ct state new等规则,最后导出至/etc/nftables.conf并启用服务。

直接上手就能用,但别跳过清空旧规则和选对协议族这两步,否则后续规则可能不生效或 IPv6 被意外放行。
怎么创建基础表和链(inet vs ip)
用 inet 表能同时管 IPv4 和 IPv6,省得建两套规则;但 NAT 类操作(如 SNAT/DNAT)必须用 ip 或 ip6,inet 不支持。生产环境推荐先建 inet filter 做过滤,再单独建 ip nat 做地址转换。
-
nft add table inet filter—— 创建双栈过滤表 -
nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }—— 输入链默认丢弃,这是白名单模式的安全基线 - 如果只跑 IPv4 且要配端口转发,改用
nft add table ip nat,否则dnat规则会报错unknown operation
怎么写一条有效的放行规则(ct state 是关键)
旧 iptables 里常用的 -m state --state ESTABLISHED,RELATED 在 nftables 中已被弃用,必须用 ct state;而且 ct state 必须放在匹配条件前,顺序错了规则就无效。
-
nft add rule inet filter input ct state { established, related } accept—— 放行已有连接(注意花括号和空格) -
nft add rule inet filter input iif lo accept—— 允许回环通信,这条必须在ct state之前加,否则本地服务调用可能失败 - SSH 放行要带协议:
nft add rule inet filter input tcp dport 22 ct state new accept——ct state new明确限定只处理新建连接,避免状态绕过
怎么保存规则并开机自启(/etc/nftables.conf 不是唯一路径)
nft list ruleset 输出的是当前运行时规则,不等于持久化配置。系统启动时加载的其实是 /etc/nftables.conf,但很多发行版(如 Ubuntu 22.04+)默认该文件为空,需要手动写入或用 nft export 生成。
- 导出当前规则:
nft export > /etc/nftables.conf(覆盖写入) - 验证语法:
nft -f /etc/nftables.conf—— 如果报错,说明文件里有非法字符或缩进问题(nftables 不认 tab 缩进,只认空格) - 启用服务:
systemctl enable --now nftables—— 注意不是nftables.service就是nftables,CentOS/RHEL 8+ 和 Debian 12+ 都用后者 - 禁用 iptables 冲突:
systemctl disable --now iptables ip6tables,否则两者规则会互相干扰
常见错误:规则写了但没生效?检查这三点
最常踩的坑不是语法错,而是链没挂到钩子、表没选对族、或者规则顺序颠倒。
-
nft list chain inet filter input看输出里有没有hook input字样——没有说明链没绑定到 netfilter 钩子,只是个空容器 -
nft list ruleset | grep -A5 "chain.*input"查看规则是否按预期顺序排列,nftables 是从上到下匹配,accept写太靠后会被前面的drop拦住 - 执行
nft add rule inet filter input tcp dport 80 accept后仍连不上,用tcpdump -i any port 80确认包是否真到了本机——如果根本没抓到,说明问题在路由或网卡层,不是防火墙的事
真正麻烦的从来不是写一条规则,而是搞清楚数据包到底走哪条链、在哪一级被拦下、状态跟踪是否开启——这些没法靠抄命令解决,得结合 nft monitor trace 和连接跟踪日志一起看。


















