chicohaager/zfw
GitHub: chicohaager/zfw
ZFW 为出厂无防火墙的 ZimaOS 提供了一个带 Web UI 和实时安全仪表板的主机防火墙模块,系统性消除局域网层面的服务暴露风险。
Stars: 4 | Forks: 1
# ZFW — 为 ZimaOS 打造的主机防火墙
ZFW 是一个独立的 ZimaOS 模块,它添加了 ZimaOS 未附带的一样东西:
一个**主机防火墙**——带有 Web UI 和实时安全仪表板。


## 为什么 ZimaOS 需要防火墙
ZimaOS 在出厂时**完全没有主机防火墙**。在全新安装的系统上,每一个 `iptables`
链 —— `INPUT`、`FORWARD`、`OUTPUT` —— 的默认策略都是 `ACCEPT`,并且不包含
任何过滤规则,同时也没有 `nftables` 规则集。这并非个别主机的配置错误,而是该操作系统的开箱即用状态。
直接的后果是:**每一个监听在 `0.0.0.0` 上的服务都可以从整个
局域网访问,操作系统中的任何机制都无法阻止它。** 这已经涵盖了
ZimaOS 本身默认附带并启用的服务:
- **Samba/SMB** (445/139) 和 **NFS + rpcbind** 协议栈 (2049/111) —— 对整个子网
开放的文件共享守护进程。端口 111 上的 `rpcbind` 是一个众所周知的
反射/放大攻击以及信息泄露的媒介。
- **发现服务** —— mDNS、WS-Discovery、SSDP/UPnP、LLMNR —— 默认
启用的广播服务。
- **内置的 VM 控制台。** 通过 ZimaOS 内置的虚拟化
模块创建的虚拟机会暴露其 VNC 控制台(端口 5900 及以上)**且无需
密码**,并绑定到所有网络接口。局域网上的任何设备都可以通过 VNC 查看器
连接它,并获得对正在运行的 VM 的完整键盘/鼠标/屏幕控制权。这是
出厂默认设置 —— 它会影响每一个运行 VM 的 ZimaOS 用户。
- **ZimaOS Web UI**(端口 80)。
然后是应用商店。ZimaOS 围绕一键安装的 Docker 应用构建,
发布的容器端口会直接映射到 `0.0.0.0` —— Docker 的端口映射
完全绕过了主机,并在应用启动的瞬间即对整个局域网开放。许多
广泛使用的自托管镜像**默认没有身份验证**:日志查看器、
指标仪表板、browser-desktop / noVNC 镜像、管理面板。如果没有主机
防火墙,此类应用在安装的那一刻就会成为网络上的一个后门 ——
而且 ZimaOS 用户的预期行为*正是*自由地安装应用;这就是该产品的核心。
最后,局域网本身已不再是可信任的边界。一个普通的家庭网络中包含
智能电视、IoT 设备、游戏机、客人的手机 —— 其中任何
一个设备被攻破,它就会成为存放您所有数据的 NAS 的直接对等节点。
ZimaOS 被宣传为专为那些
明确*不是*网络工程师的人设计的即插即用 homelab/NAS 设备。期望每个用户手动审计服务
绑定是不切实际的。防火墙是唯一能够一次性消除这类
暴露问题的系统性控制措施。这正是 ZFW 所提供的。
## ZFW 的功能
一个独立的 ZimaOS 模块 —— ZimaOS 仪表板中的一个磁贴 —— 包含五个部分:
- **防火墙** —— 实时状态;带有 120 秒死人开关的 **Safe-Apply**,如果您没有及时确认,它会
自动撤销规则,因此糟糕的规则永远不会将您锁在外面;提交;撤销。
- **允许列表** —— 通过点击即可编辑可从局域网访问的端口 —— 无需 SSH,
无需编辑文件。
- **暴露面** —— 实时显示每个正在监听的 TCP 端口,并进行分类:可从局域网访问 /
被 ZFW 阻止 / 仅限回环。
- **审计** —— 一个安全发现目录,每一项都会针对
当前防火墙配置进行实时重新评估(未决 / 局域网已阻止 / 已修复)。
- **版本** —— 主机的关键组件及其已知的 CVE 状态。
## 工作原理
ZFW 在**两个钩子点**进行过滤,因为 ZimaOS 上的流量走的是两条独立的路径:
| 钩子 | 过滤对象 | 模式 |
|------|---------|------|
| `INPUT` (链 `ZFW-IN`) | 主机原生守护进程 (SSH、Web UI、SMB、NFS 等) | 默认拒绝的允许列表 |
| `DOCKER-USER` | 发布的 Docker 容器端口 | 黑名单 |
单一的 `INPUT` 防火墙是不够的:**Docker 发布的端口从不遍历
`INPUT`** —— 它们被 DNAT 并通过 `FORWARD` 路由。`DOCKER-USER` 是 Docker
官方的、保证不被触碰的用户钩子,因此 ZFW 在那里过滤容器端口。
`localhost`、主机自身的 IP 以及 `tailscale0` / ZeroTier 接口始终被
允许 —— 因此 VPN 访问和隧道客户端(例如 Pangolin/Newt)永远不会受到影响。
ZFW 仅管理 **LAN** 边界。
## 架构
ZFW 分为两层:
- **引擎** —— `/DATA/zfw/zfw`,一个 shell 脚本外加 `allowlist.conf`。它应用
`iptables` 规则,以 root 身份从 systemd 单元运行,并支持死人
`--safe` 模式。
- **模块**(本仓库)—— 一个 Go 守护进程 (`zfwd`) 和 Web UI。守护进程
**仅绑定 `127.0.0.1`**;ZimaOS 网关会代理路由 `/v2/zfw`,以便
UI 可以通过 80 端口在同源下访问。因为网关转发模块路由时
**不对其进行身份验证**,所以守护进程在每个 API 请求时都会验证有效的 ZimaOS 会话
token(一个 ES256 JWT,根据平台 JWKS 进行校验)——
防火墙自身的控制面板绝不能成为防火墙中的一个未验证漏洞。
```
cmd/zfwd daemon entry point
internal/firewall control plane: wraps the engine + allowlist.conf, reads live state
internal/system listening-port scan, component versions
internal/audit finding catalogue, scored live against the firewall config
internal/gateway ZimaOS gateway route registration
internal/watchdog boot watchdog (ZimaOS sysext units can lose the boot race)
raw/ the sysext file tree (binary, systemd unit, manifest, static UI)
```
## 构建
```
sh build.sh # -> dist/zfw-
-.tar.gz (per arch)
```
默认架构:`amd64` (ZimaBoard 1/2、ZimaCube) 和 `arm64` (Lattepanda/树莓派类
主机)。使用 `ARCHES="amd64" sh build.sh` 覆盖以构建单一架构。
需要 `go` 1.22+ 和 `squashfs-tools` (`mksquashfs`)。镜像使用
gzip 打包 —— ZimaOS 内核在构建时没有加入 zstd/xz 的 squashfs 支持。
## 部署
`build.sh` 会为每种架构生成一个发布包 —— `dist/zfw--.tar.gz`
包含 `zfw.raw` 模块、`zfw` 引擎脚本、`install.sh` 和文档。
将匹配架构的安装包复制到 ZimaOS 主机上,并以 root 身份运行安装程序:
```
scp dist/zfw--amd64.tar.gz root@:/tmp/ # ZimaBoard / ZimaCube
ssh root@ 'cd /tmp && tar xzf zfw--amd64.tar.gz && cd zfw-* && sh install.sh'
```
`install.sh` 会将 sysext 模块放置在 `/var/lib/extensions/` 中,将
引擎脚本安装到 `/DATA/zfw/zfw` (`root:root`、`0700`),校验模块
校验和,合并 sysext 并(重新)启动 `zfw-ui.service`。随时
重新运行它以原地更新安装。
从 ZimaOS 仪表板(磁贴 **ZFW Firewall**)或直接在
`http:///modules/zfw/index.html` 打开它。
## 配置
允许列表可以从 UI 中编辑,或直接在 `/DATA/zfw/allowlist.conf` 中编辑:
| 键 | 含义 |
|-----|---------|
| `LAN` | 本地子网,例如 `192.168.1.0/24` |
| `HOST_IP` | 主机的局域网 IP |
| `HOST_TCP_LAN` / `HOST_UDP_LAN` | 保持可从局域网访问的主机原生端口;其他所有流量均被丢弃(仍可通过 Tailscale / 回环访问) |
| `DOCKER_DROP_LAN` | 要从局域网阻止的已发布容器端口 |
| `V6_DROP` | 要在 IPv6 上阻止的端口 |
进行任何更改后,请从 Firewall 标签页运行 **Safe-Apply**(或在主机上运行 `zfw apply`)。
## 安全
通过网络应用防火墙规则是有风险的 —— 一个错误的规则可能会将您锁在外面。
ZFW 的 **Safe-Apply** 会应用规则并启动一个 120 秒的计时器;除非您在该时间窗口内点击
**确认**(或运行 `zfw commit`),否则规则将自动撤销。当前的 SSH 会话永远不会被断开 —— 已建立的连接会被
优先接受。
有关完整的操作指南 —— 保持可访问性、规则排序、地理封锁
限制和恢复 —— 请参阅 **[BEST-PRACTICES.md](BEST-PRACTICES.md)**。标签:Docker安全, EVTX分析, iptables, TCP SYN 扫描, Web UI, ZimaOS, 主机防火墙, 日志审计, 网络安全, 网络流量过滤, 隐私保护