firewalld虚拟化网络隔离核心是按虚拟网络类型绑定zone并用source绑定与富规则实现逻辑隔离,需绕过接口绑定限制,优先匹配source、启用ip转发、禁用networkmanager接管虚拟设备,并统一由firewalld管理规则。

Linux 使用 firewalld 隔离虚拟化网络区域,核心是把不同虚拟网络(如桥接网卡、VLAN 子接口、容器宿主机接口)映射到不同 trust 级别的 zone,并配合 source 绑定与富规则实现逻辑隔离。物理接口归属单一 zone 的限制在虚拟化场景下尤为明显,必须绕过“接口绑定”思维,转向“流量来源识别”逻辑。
按虚拟网络类型绑定对应区域
虚拟化环境常见网络结构包括:libvirt 默认的 virbr0(NAT 模式)、Open vSwitch 桥 br-int、KVM 虚拟机直通的 ens3f0.100(VLAN 子接口)、Pod 网络出口如 cni0 或 flannel.1。这些不能简单当作普通网卡处理:
- virbr0(NAT 虚拟网络)适合绑定 external 区域:启用 masquerade,允许内部虚拟机访问外网,但默认拒绝外部主动连接
- br-int / ovs-br0(OpenStack 或 OVS 管理平面)建议用自定义区域如 ovs-mgmt,仅放行 ssh、https、ovsdb-server 端口
-
VLAN 子接口(如 ens3f0.100)应避免直接绑定 zone;改用 source 绑定其所属子网,例如:
firewall-cmd --permanent --zone=dmz --add-source=10.20.100.0/24 - cni0 / flannel.1(容器 Pod 网络)不建议绑定任何 zone —— 容器通信应由 CNI 插件自身策略或 kube-proxy 控制;firewalld 只需保护宿主机端口,可将其归入 internal 并显式屏蔽容器 IP 段以外的访问
用 source 绑定替代接口绑定,支持多子网共存
一台宿主机常承载多个虚拟网络段(如 192.168.100.0/24 是测试 VM 网段,10.30.5.0/24 是生产容器网段),它们可能都走同一物理口(如 eth0)。此时必须放弃 --change-interface,改用 source 方式划分策略:
- 将测试网段归入 home 区域:
firewall-cmd --permanent --zone=home --add-source=192.168.100.0/24 - 将生产容器网段归入 internal 区域:
firewall-cmd --permanent --zone=internal --add-source=10.30.5.0/24 - 确保未匹配 source 的流量落到默认 zone(如 public),防止策略遗漏
- firewalld 匹配顺序为:source → interface → default zone,所以 source 规则优先级最高
用富规则控制跨区域访问(如宿主机只响应特定虚拟机的数据库请求)
预定义区域太粗粒度,例如 internal 默认放行所有服务,但你只想让某台管理虚拟机(192.168.100.50)能连宿主机的 PostgreSQL(5432):
- 先确认该虚拟机 IP 已被 source 绑定到某个 zone(如 home)
- 在 home zone 中添加富规则:
firewall-cmd --permanent --zone=home --add-rich-rule='rule family="ipv4" source address="192.168.100.50" port port="5432" protocol="tcp" accept' - 同时在 home zone 中禁用其他端口(可选):
firewall-cmd --permanent --zone=home --set-target=REJECT - 注意:这条规则只对走 home zone 的流量生效;若该 IP 实际被误判进 public zone,则规则不触发
关键配套设置不能漏
光配 firewalld 不足以完成虚拟化网络隔离,还需同步检查以下项:
-
开启 IP 转发(否则跨网段虚拟机无法通信):
echo 'net.ipv4.ip_forward = 1' > /etc/sysctl.d/99-ipforward.conf && sysctl -p -
禁用 NetworkManager 对虚拟桥接设备的接管(避免它重置 firewalld zone 绑定):在
/etc/NetworkManager/conf.d/10-no-bridge.conf中添加[keyfile] unmanaged-devices=interface-name:virbr0;interface-name:br-int -
确认 libvirt 或容器运行时未绕过 firewalld:例如 Docker 默认启用
--iptables=false时会自行管理规则,与 firewalld 冲突;建议统一交由 firewalld 管理,Docker 启动时加--iptables=true并禁用其自动规则(通过/etc/docker/daemon.json设置"iptables": false仅在明确需要时) -
重启并验证:
firewall-cmd --reload,再用firewall-cmd --get-active-zones和firewall-cmd --zone=home --list-all确认 source 和规则已加载











