改 iptables 把自己锁外面那件事,我研究了下解法

上周五下班前我做了件蠢事:在远端的 Linux 服务器上改 iptables 规则想加一条放行,结果 NAT 链顺序写反了,flush 之后规则没补回去。当时人已经在地铁上,发现连不上的时候一身冷汗。SSH 进去补规则也没用——我自己把入口给关死了,最后只能等第二天物理接触机器才恢复。

这种事干一次就够了。我开始认真找有没有”改完规则先试再确认”的工具,而不是一上来就生效。结果翻到一个叫 easywall 的项目,今天(8 月 5 日)刚发了 v2.4.1,半年多从 v2.0.0 一路推到 v2.4.1,迭代节奏比很多防火墙工具都勤快。它的设计刚好踩在我这个痛点上:每条规则点 Apply 之后,只会生效 120 秒,你要在窗口期内手动点 Confirm 才算正式落定;如果你被自己的规则踢出门了——啥也不用做,等 120 秒它自己回滚回去。

它不是新项目,但 2022 年那次断档值得讲一下

easywall 这个名字第一次出现是 2017 年。最早是 Python 写的,Flask 做 Web,iptables 通过 subprocess 调用。这套架构在 2022 年因为一个 CVE 直接归档了——两个根因:一个是 Web 进程本身有 root 权限(攻击面大),另一个是 subprocess 拼命令执行(注入风险)。

2026 年 4 月 26 日,作者把整个项目用 Go 重写,出了 v2.0.0,底层从 iptables 切到 nftables。这两个根因都没了:

  • Web 进程不再有 root——拆成两个进程:easywall-core 跑 root 直接通过 netlink 操作 nftables 内核表,easywall-web 用 chi 路由 + html/template + HTMX 跑普通用户;两者通过 Unix socket(0660 权限)走类型化 JSON 协议通信。Web 进程被攻破也拿不到防火墙权限。
  • 不再走 subprocess——通过 google/nftables 这个库直接构造 Go struct 调 netlink,没有 shell 拼接。

easywall 两步激活流程,120 秒回滚窗口

从 v2.0.0 到今天的 v2.4.1,差不多 3 个半月发了 14 个版本,平均一周多一个。这种节奏在防火墙工具里相当少见——大多数同类项目都是半年憋一个大版本。说明作者把这件事当正事在做。

120 秒回滚到底怎么实现的

这个机制是整个项目最聪明的地方。规则有三个状态:current(当前生效)staged(编辑中但未应用)backup(回滚用的快照)。所有改动先进 staged,不动 current。

点 Apply 之后发生的事:

  1. 把当前规则快照存到 backup
  2. 把 staged 规则推给 nftables 内核(这是新规则开始生效的窗口)
  3. 启动一个 120 秒的定时器
  4. 如果 120 秒内 Web 端点 Confirm → 把 backup 扔掉,新规则变成 current
  5. 如果 120 秒内 Web 端点没收到 Confirm(最常见的情况:你已经被新规则踢出去了)→ 自动把 backup 恢复回 current

关键是这个窗口期内新规则已经生效了,你能立刻感受到变化。如果它把你关在门外,恰好你连不上 Web——这正是它的设计意图:什么都不做就是最对的反应,等时间到了它自己救你。

回滚时间长度在 v2.2.0 之后可以从前端配置改,不用改配置文件。窗口期短的好处是误操作后恢复快;长一些的好处是远程操作时能从容确认——这个看你怎么用了。

9 个保护模块,4 个默认开

easywall 系统选项/保护模块

easywall 内置 9 个保护模块:

  • SSH 暴力破解防护——每源 IP 连接数限制
  • ICMP flood——ping 洪水限速
  • SYN flood——新 TCP 连接限速
  • 端口扫描——NULL/FIN/XMAS/SYN+FIN 探针直接 DROP
  • 非法包丢弃——ct state invalid → DROP
  • IP 分片丢弃
  • Bogon 过滤——RFC-1918 私网地址从公网接口来的直接 DROP(防伪造)
  • 连接数限制——每源 IP 同时连接数上限
  • 广播/组播/TCP RST 限速

前 4 个默认开启,剩下 5 个按需打开。SSH 那个 alpha 状态我还没在生产开过,理论上有个问题:如果你的服务器在 NAT 后面,源 IP 全是同一个网关,反而把自己限了。这个得看场景。

整体上这一套对家用 Linux 服务器、暴露在公网的 VPS 来说够用——Bogon 过滤和端口扫描防护是大多数裸奔服务器缺的东西。

Docker 兼容性是认真做过的

这是我比较在意的点。我服务器上跑了一堆 Docker 容器,最怕防火墙面板一刀切把容器网络也 ban 了。easywall 处理这个的思路是:

自己拥有 inet easywall 这张 nftables 表,跟 Docker 的 chain 完全不交叉。Docker 用的是 bridge/filter/forward 和它自己的一套 nat,easywall 不会去碰。如果有需要跟容器网络交互,v2.1.0 加了 GET/POST /settings 专门配置 IPv6 和 Docker 网络的 CIDR。

我读 v2.0.0 的 commit 列表还看到过专门修 Docker CIDR 掩码处理的 PR——之前某个版本会 panic,这种 corner case 都补上了。

部署方式有三种,按你的环境选

easywall 端口管理界面

第一种是 Debian/Ubuntu 的 deb 包,最简单:

wget https://github.com/jp1337/easywall/releases/latest/download/easywall_amd64.deb
sudo dpkg -i easywall_amd64.deb && sudo apt-get install -f

装完直接 systemctl enable --now easywall-core easywall-web,浏览器开 https://localhost:12227,第一次进有初始化向导。

第二种是 Docker Compose,适合想跑在容器里测试的人:

git clone https://github.com/jp1337/easywall.git && cd easywall
docker compose up -d

但要注意:跑在容器里意味着 easywall-core 也得能管宿主机的 nftables,需要 privileged 或者把 netlink socket 透传过去。生产我建议还是 deb 装到宿主机。

第三种是源码编译,Go 1.25+:

git clone https://github.com/jp1337/easywall.git && cd easywall
make build
sudo make install

三个产物:easywall-core(root 跑的守护进程)、easywall-web(普通用户跑的 Web)、systemd unit 文件。

权限模型这块是它最大的卖点

最后单独讲一下,因为它跟大多数同类工具的思路完全不同。常见的 Web 面板类防火墙(nft-ui、go-port-forward、nftables-nat-rust 这些)都是单一进程,整进程跑 root 或者 sudo。Web 端一旦被攻破,攻击者直接拿到防火墙控制权。

easywall 的做法是把 root 权限压到最小集合——只有 easywall-core 一个进程拿 root,且它只通过 netlink 跟 nftables 内核表通信,不监听任何 TCP 端口。Web 端 easywall-web 完全跑普通用户,监听 HTTPS(默认 12227)。两者之间只走 Unix socket(0660 权限,只有 easywall 组能读)。

Web 进程被 XSS/CSRF 攻破 → 攻击者能改配置草稿,但改不了生效规则。Web 进程被 RCE → 攻击者也只能通过 socket 提权到 easywall-core,触发 daemon 弹出一个”非预期配置变更”,你看一眼日志能发现。这种”双进程隔离 + 类型化 IPC”在网关类工具里很少见——大多数同类项目都懒得做这一步。

Roadmap 还没做但已经列出来了

项目主页上的 Roadmap 写了四件事:

  • 2FA / TOTP——Web 端第二因子认证
  • Let’s Encrypt ACME——不依赖反向代理就能签证书
  • 登录审计日志——目前审计日志只记规则变更,不记认证事件
  • REST API——给 Ansible 和自动化用

我个人最期待 REST API。如果有了,理论上可以写 Ansible playbook 批量管理多台机器的防火墙规则,配上 Git 做版本控制,CI 里跑一次 diff 看看改动合不合理再 apply——这才是现代基础设施该有的样子。

2FA 那个其实应该排在更前面,毕竟它现在所有认证都靠单一密码。

适配场景和局限

适合用 easywall 的情况:

  • 有 1-2 台 Linux 服务器跑在公网或者 DMZ,自己管防火墙规则
  • 愿意花 10 分钟装一下、用 Web 而不是直接 ssh 上去改脚本的人
  • 出过”被自己锁外面”事故、不想再出的人

不太适合:

  • 软路由主控——它不像 OpenWrt firewall 或者 iptables 脚本那样是”无状态、可纳管进配置管理”的形态,更像是一个交互工具;如果你的软路由是 OpenWrt,Luci 已经够用
  • 集群规模——单机工具,没有原生的多机协同;虽然 Roadmap 有 REST API,但还没影
  • 极端性能场景——它每次 Apply 都过完整 IPC 协议 + 重新生成 nftables 规则集,规则上万条量级会慢

还有个值得提的:项目 star 数还很少,重写后刚开始重新积累关注度。GPL-3.0 协议,长期看不太担心作者跑路,但单点故障(一个人维护)要心里有数。如果你要在生产上用,建议 fork 一份到自己的 namespace,留个后手。

v2.4.1 这次的更新主要是 CodeQL redirect guard 加固 + 暗色模式文档站修复 + 几处文档错误更正,没有引入破坏性变更。我自己的策略是先在测试环境跑一两周,看 9 个保护模块的默认配置有没有把日常 SSH 流量误杀——再决定要不要上生产。

如果一切顺利,理论上以后改防火墙规则这件事可以告别”深呼吸-回车-祈祷三连”了。

发表评论