众所周知,firewalld 会在重新加载时刷新 Libvirt 规则,因此导致虚拟机的端口转发中断,直到您重新启动 libvirtd。以下是我所做的:
- 创造
/etc/systemd/system/firewalld-reload-hook.service
[Unit]
Description=firewalld reload hook - run a hook script on firewalld reload
Wants=dbus-broker.service
After=dbus-broker.service
[Service]
Type=simple
ExecStart=/bin/bash -c '/bin/busctl monitor --system --json=short --match "interface=org.fedoraproject.FirewallD1,member=Reloaded" | while read -r line ; do [ -x /sbin/firewalld-reload-hook ] && /sbin/firewalld-reload-hook ; done'
[Install]
WantedBy=multi-user.target
- 创造
/sbin/firewalld-reload-hook
#!/bin/bash
# Invoked by /etc/systemd/system/firewalld-reload-hook.service
set -e
logger "$BASH_SOURCE: Firewalld reload hook triggered."
/usr/bin/systemctl restart libvirtd
logger "$BASH_SOURCE: Libvirt restarted."
exit 0
并使其可执行chmod +x /sbin/firewalld-reload-hook
- 安装
libvirt-hook-qemu
git clone https://github.com/saschpe/libvirt-hook-qemu.git
make install
/etc/libvirt/hooks/hooks.json
根据您的需要进行编辑。这只是一个例子
{
"www": {
"private_ip": "192.168.122.100",
"port_map": {
"tcp": [80, 443]
}
},
"mail": {
"private_ip": "192.168.122.101",
"port_map": {
"tcp": [25, 465]
}
}
}
- 启用并启动
firewalld-reload-hook.service
systemctl enable firewalld-reload-hook.service
systemctl start firewalld-reload-hook.service
firewall-cmd --reload
此时systemctl restart libvirtd
产生firewall-cmd --reload
相同的结果并在重启后继续存在(在 Debian bullseye 上使用 nftables 和 libvirt 7.0/NAT 网络进行测试)
那么,这是最好的方法吗?