未来星球 未来星球
  • 首页
  • 新闻资讯
  • 技术教程
  • 软件工具
  • 知识百科
  • 生活实用
  • 个人随笔
  • 生命外星人
首页 › 技术教程 › 用 nftables 重写 iptables 规则:一份可复现的迁移对照表
  • 0
  • 0

用 nftables 重写 iptables 规则:一份可复现的迁移对照表

admin
2 小时前
1 views
用 nftables 重写 iptables 规则:一份可复现的迁移对照表-未来星球

改到第四十条规则时,你就不敢再动了

用 iptables 管过服务器的人都有这个时刻:规则表写到四十条,某天要开一个新端口,你盯着屏幕看了三分钟,不确定插在哪一行——因为不知道哪一条正在挡着 SSH。

这不是能力问题,是工具问题。iptables 把「表、链、规则」拆成三套命令,插入位置靠行号,查一条规则要 `iptables -L -n –line-numbers` 再看一遍,改一条要 `-I` 加数字。规则一多,维护成本就不是线性增长的。

nftables 解决的不是性能——多数场景下两者的转发性能差异可以忽略。它解决的是「你还敢不敢改」这个问题。

1. 两套模型的对应关系

先建立映射,后面才不迷路。iptables 的「表」在 nftables 里还叫 table,但多了一层「族」(family)的概念,而「链」和「规则」被合并进了同一份文本。

iptables 概念 nftables 对应 关键差异
filter / nat 表 table inet filter inet 族可同时处理 IPv4 与 IPv6,不必写两遍
INPUT / OUTPUT 链 chain input { type filter hook input ... } hook 与 type 写在链定义里,不再是隐式约定
iptables -A/-I 直接写在链的花括号里 顺序即文件顺序,看得见
-m state --state ct state 连接跟踪改为 ct 表达式
-m recent meter / 动态 set 原模块没有直接对应,要用集合重写

最重要的一条差异在最后:nftables 允许你在一个 table 里放任意多条链,且链与链之间可以互相跳转。这让「按用途分链」成为可能——SSH 一条链、Web 一条链、Docker 一条链,出问题时能一眼定位是哪一块在生效。

2. 一份能直接用的最小配置

下面是整份配置文件,一台只跑 SSH 和 80/443 的机器的完整版本。请注意它是一份**整体**,不是逐条追加——nftables 的加载单位是文件,不是命令行。

#!/usr/sbin/nft -f
flush ruleset

table inet filter {
  set blackhole {
    type ipv4_addr
    flags dynamic, timeout
    timeout 1h
  }

  chain input {
    type filter hook input priority filter; policy drop;

    iif lo accept
    ct state established,related accept
    ct state invalid drop

    ip protocol icmp accept
    ip6 nexthdr icmpv6 accept

    tcp dport 22 ct state new limit rate 6/minute burst 4 packets accept
    tcp dport { 80, 443 } ct state new accept

    ip saddr @blackhole drop
  }

  chain forward {
    type filter hook forward priority filter; policy drop;
  }

  chain output {
    type filter hook output priority filter; policy accept;
  }
}

几个必须解释的地方:

policy drop 写在链定义那一行,不是最后一条规则。它是默认verdict,所有没命中的包都走这里。这也是最容易出事的地方——一旦 flush 之后没接上新规则,SSH 立刻断。

ct state established,related accept 必须排在所有新连接规则之前。它放行的是「已建立连接的回包」,缺了它,你发出去的请求回不来,表现是能 ping 通但什么都连不上。

iif lo accept 不能省。很多本机服务(数据库、缓存、localhost 调用)走回环,默认 drop 会把它们全部掐死,而报错信息通常指向应用层,查半天查不到防火墙。

ICMP 和 ICMPv6 要分开放。只放 ICMP 的话,IPv6 会因为邻居发现(NDP)失败而整段不通,表现是「IPv4 正常,IPv6 超时」,很容易误判成运营商问题。

3. 六组语法对照,照着换就行

迁移时九成的改写量集中在这六组。左边是你现在写的,右边是等价的 nftables 写法。

iptables nftables
-p tcp --dport 22 -j ACCEPT tcp dport 22 accept
-s 10.0.0.0/8 -j ACCEPT ip saddr 10.0.0.0/8 accept
-m multiport --dports 80,443 tcp dport { 80, 443 }
-m state --state NEW,ESTABLISHED ct state new,established
-j LOG --log-prefix "DROP:" log prefix "DROP: " level warn
-j DNAT --to-destination 10.0.0.5:8080 dnat to 10.0.0.5:8080

注意第三行:花括号集合替代了 multiport 模块,而且是原生的。端口可以写成区间 `1024-2048`,也可以混合 `{ 22, 80, 443, 8000-8100 }`。这一处改写最省事。

还有一处容易漏:nftables 默认不计包数。iptables 每条规则自带计数器,nftables 需要显式写 `counter`。想看哪条规则在命中,必须加这个词。

4. 三个必然踩到的坑

坑一:Docker 会把你的规则顶掉。Docker 仍然通过 iptables 接口写规则,在 nft 后端下这些规则会落进它自己创建的 `ip filter` 和 `ip nat` 表。你在 `inet filter` 里设了 `policy drop`,但 Docker 发布端口时写的是 DNAT + ACCEPT,两者不在同一个 table,结果是「容器端口对外可达,但你的防火墙规则看起来完全没生效」。排查时一定要 `nft list ruleset` 看全量,不要只看自己那张表。

坑二:flush ruleset 之后连接就断了。因为旧规则被清空的那一瞬间,默认策略回到 accept,紧接着你加载新规则、设成 drop——如果中途 sshd 正好有个包在飞,或者加载失败,你就被锁在门外。正确做法是先挂一个自动回滚,再动手:

# 15 分钟后无条件清空规则,给自己留后路
systemd-run --on-active=15min --unit=nft-rollback \
  nft flush ruleset

# 确认新规则工作正常后,取消这个定时器
systemctl stop nft-rollback.timer

这招救过很多人。它不优雅,但比半夜叫机房重启强。

坑三:规则文件加载不是原子的,但整份替换是。`nft -f` 读取文件时是逐条执行的,中途语法错会停在一半,留下一个残缺规则集。所以上线前必须用 `nft -c -f /etc/nftables.conf` 做一次仅检查不执行的语法验证。这一步能拦掉八成事故。

5. 迁移的实操顺序

不要一次性替换。按下面五步走,每一步都可回退:

  1. 先把现有 iptables 规则导出成文本:`iptables-save > /root/iptables.bak`。这是唯一的退路。
  2. 用 `iptables-restore-translate` 生成初版:它会输出一份等价的 nft 规则,不要直接用,但要拿它做语法参照,省掉大量查文档的时间。
  3. 在独立 table 里并行跑:新建 `table inet staging`,只挂 log 不挂 drop,观察一晚命中情况。
  4. 确认无误后切换到主 table:带上面那个 15 分钟回滚定时器。
  5. 关掉旧后端:`update-alternatives –set iptables /usr/sbin/iptables-nft`,避免两套规则同时生效互相干扰。

第三步值得多说一句。用 log 代替 drop 做灰度,是防火墙改造里最被低估的手法——你能看到「假如现在就 drop,会错杀哪些流量」,而代价只是日志多几行。

6. 上线后的验收

三条命令,五分钟:

  1. `nft list ruleset` 输出完整、无报错,且 `policy drop` 出现在 input 链上。
  2. 从外部扫一遍:`nmap -Pn -p 1-1000 你的IP`,只应看到 22/80/443。
  3. 本机验证回环没被误伤:`curl -s localhost:你的服务端口`,应当有响应。

第三条最容易被跳过,也最容易在上线两小时后被业务方找上门。防火墙改完,第一个该测的不是外网,是本机。

写在最后

从 iptables 到 nftables,表面是语法变了,实质是把「一堆命令的执行历史」变成了「一份可以被阅读的文档」。前者只能靠记忆和试探维护,后者可以 review、可以进版本库、可以 diff。

这件事的价值不在于你少敲了几个字母,而在于半年后接手的人——可能是别人,也可能是你自己——打开那份文件,能看懂它想干什么。

运维里最难的不是配通,是配通之后还敢改。所有让人不敢改的配置,迟早会烂在那里。


你的服务器上,防火墙规则是写在一个文件里,还是一串散落在历史记录里的命令?

0

拉链为什么不会自己松开:一个齿和一个楔

上一篇

剪贴板管理器四选一:Ditto、CopyQ、Maccy 与系统剪贴板的适用边界

下一篇

评论 (0)

登录后可发布~
立即登录
暂无评论

admin

当生活给你的全是不如意,那你一定要相信自己的兴趣!
129
文章
0
评论
-11
喜欢
2026 年 10 月
一 二 三 四 五 六 日
 1234
567891011
12131415161718
19202122232425
262728293031  
« 9 月    

近期评论

聚合文章

当机器开始替你判断:自动化留给人最后的那一段
参宿四 2019 年的大变暗:一次抛射、一层尘埃,和一个还没到来的结局
阳台那盆绿萝活了六年,我一次没给它换过土
AI 新闻日报 – 2026年10月29日:一个不敢开放的模型,和一张跌了 7% 的财报
洗衣机用了两年开始有味道:一份从胶圈到排水泵的排查清单
剪贴板管理器四选一:Ditto、CopyQ、Maccy 与系统剪贴板的适用边界
用 nftables 重写 iptables 规则:一份可复现的迁移对照表
拉链为什么不会自己松开:一个齿和一个楔

猜你喜欢

用 SQLite 当生产数据库:WAL 模式、并发上限与备份策略的完整配置

用 SQLite 当生产数据库:WAL 模式、并发上限与备份策略的完整配置

admin
13 0 0
普通人如何用AI赚钱?2025最全实操指南

普通人如何用AI赚钱?2025最全实操指南

admin
50 0 0
2026 年必学的 5 个 AI 提示词技巧

2026 年必学的 5 个 AI 提示词技巧

admin
94 0 0
用 systemd timer 替代 cron:失败重试、日志与错峰执行的完整配置

用 systemd timer 替代 cron:失败重试、日志与错峰执行的完整配置

admin
16 0 0

关于我们

你是否对浩瀚的宇宙充满好奇?你是否渴望掌握未来科技的力量?现在,机会来了!“未来星球”将带你进入奇妙世界,开启你的科技探险之旅! 这是一个充满想象和创造力的博客!

分类导航

首页 新闻资讯 技术教程 软件工具 知识百科 生活实用 个人随笔 生命外星人

友情链接

未来星球AI工具【网络版】 未来星球 pycharm官方站【中国】
Copyright © 2026 未来星球. Designed by nicetheme. 蒙ICP备2026002569号-1
  • 请到 [后台->外观->菜单] 中设置菜单
  • AI未来
  • 生活百科
  • 档案
  • 外星人
  • 未来星球

admin

当生活给你的全是不如意,那你一定要相信自己的兴趣!
129
文章
0
评论
-11
喜欢