"DC 层规则 + 节点层开关"的配合关系
一、PVE 防火墙的三层架构(从内到外)
┌─────────────────────────────────────────────────┐
│ 数据中心层 │
│ /etc/pve/firewall/cluster.fw │
│ [RULES] 全局规则 │
│ [group xxx] 规则组 │
│ [IPSET] 仅用 GUI 管理 │
│ ┌─────────────────────────────────────────────┐ │
│ │ 节点层(宿主机) │ │
│ │ /etc/pve/nodes/<主机名>/host.fw │ │
│ │ [RULES] 仅节点自己的 INPUT 规则 │ │
│ │ ┌───────────────────────────────────────┐ │ │
│ │ │ VM/CT 层 │ │ │
│ │ │ /etc/pve/firewall/<VMID>.fw │ │ │
│ │ │ 每个 VM 独立的规则 │ │ │
│ │ └───────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘二、两个独立开关
PVE 有两个物理上独立的开关,不是总开关和子开关的关系,而是"总开关"和"宿主开关"并列:
| 开关 | 位置 | 文件 | 控制什么 |
|---|---|---|---|
| ① 数据中心开关 | 数据中心 → 防火墙 → 选项 | dc/fw.cfg 或 cluster.fw [OPTIONS] enable | 整个防火墙系统是否运行(编译规则、生成链) |
| ② 节点开关 | 节点 bitsDE → 防火墙 → 选项 | host.fw [OPTIONS] enable | 是否把规则挂到这台宿主的 INPUT 链上 |
都开 = 正常工作;只开①不开② = 规则编译了但没挂到宿主 INPUT(表现为你的 8006 DROP 无效)。
类比:① 是"是否造房子"(编译规则);② 是"是否把门打开让房子能进风"(挂 INPUT 链)。你的水泥(规则)已经浇好了,但门没开,风进不来。
三、规则气流图(数据包走哪条路)
以从外部访问 bitsDE 的 8006 为例:
外部 IP 访问 bitsDE:8006
↓
① 网卡收到包
↓
② INPUT 链(内核)
↓
③ pve-firewall 的挂钩(仅当节点开关 ② 开启时才存在)
↓
④ PVEFW-INPUT 链
↓ (里面内容按顺序处理)
┌─────────────────────────────────┐
│ 自动规则: │
│ INVALID DROP │
│ ESTABLISHED/RELATED ACCEPT │
├─────────────────────────────────┤
│ 节点层规则: host.fw [RULES] │ ← 你有空,所以跳过
├─────────────────────────────────┤
│ 数据中心层规则: cluster.fw │ ← 你的 8006 DROP 在这里
│ [RULES] │
│ GROUP nm-tail │
│ IN DROP -dport 8006 │
├─────────────────────────────────┤
│ 默认策略(policy_in) │
└─────────────────────────────────┘
↓
⑤ 匹配 DROP → 包被丢弃 ✓关键:③ 只在节点开关开启时存在。不开 → 流量直接跳过整个④ → 规则不生效。
四、规则优先级和覆盖关系
数据包到达宿主机 INPUT 后,依次匹配:
1. PVEFW-Drop(自动保护规则) ← 自动,不可配置
2. ESTABLISHED/RELATED ACCEPT ← 自动,不可配置
3. host.fw 的节点层规则 ← 节点层,优先级最高
4. cluster.fw 的数据中心层规则 ← 数据中心层,优先级次之
5. policy_in 默认策略 ← 没被任何规则匹配时走这里重要原则:
- 节点层规则(host.fw)先于数据中心层规则(cluster.fw)匹配。 同一条规则,在 host.fw 写比在 cluster.fw 写优先级更高。
- 同一层内,先写先匹配(所以你的 8006 DROP 必须放在 GROUP 后面,否则 GROUP 的 ACCEPT 永远不生效)。
- 节点层规则只针对这一台机器;数据中心层规则对集群内所有节点都生效(前提是各节点开关都开了)。
五、你现在的最佳实践(确诊后)
| 配置 | 建议 |
|---|---|
| 数据中心开关 | 保持开启(已开) |
| 所有节点的开关 | 全部开启(你之前不开,是那次失效的根本原因) |
| 规则写在 DC 层 | 放 cluster.fw,一次配置,所有节点共享 |
| 节点层 host.fw | 留空 [RULES] 即可,只放 enable: 1;不写规则,全部继承 DC 层 |
你的节点已经统一啦:bitsDE 开了节点开关,原先 DC 层的 8006 DROP 就能生效了。ultra4 和 solidla 如果也开了节点开关,同样的规则会同步生效——但前提是它们在同一个集群内。如果不在同一集群,每台集群的 cluster.fw 需要各自配置。
六、验证方法(你现在已经知道怎么看了)
# 看 compile 是否有 "ignore INPUT" —— 没有 = 节点开关生效
pve-firewall compile 2>&1 | grep -i "ignore INPUT"
# 看规则是否在 iptables 里
iptables -L PVEFW-INPUT -n --line-numbers | grep 8006
# 看双开关状态
echo "DC 开关:"; cat /etc/pve/firewall/dc/fw.cfg 2>/dev/null | grep enable
echo "节点开关:"; cat /etc/pve/nodes/$(hostname -s)/host.fw | grep enable现在你理解了"双开关"机制,之后配置其他节点就知道:**DC 层写规则,每台节点开自己的开关,规则就统一生效了。