我在 处设置了一个钩子,/etc/libvirt/hooks/qemu
其权限为 755,所有者为 0:0,其内容如下:
#!/bin/bash
if [ "${1}" = "virtualmachine" ]; then
GUEST_IP=192.168.122.2
GUEST_PORT=1234
HOST_PORT=1234
if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
/sbin/iptables -D FORWARD -o virbr0 -d $GUEST_IP -j ACCEPT
/sbin/iptables -t nat -D PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
fi
if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
/sbin/iptables -I FORWARD -o virbr0 -d $GUEST_IP -j ACCEPT
/sbin/iptables -t nat -I PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
fi
fi
但是当我启动它并尝试通过telnet 192.168.1.1 1234
(我知道这不是“正确的”,只是检查端口转发)进行连接时,它失败了。服务正在运行,可以通过专用端口直接连接。但是我无法保留专用端口,因为我无法为每个虚拟机分配一个物理端口。
主机运行 Ubuntu 服务器 19.04,而客户机运行 Debian 10。
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT udp -- anywhere anywhere udp dpt:domain
ACCEPT tcp -- anywhere anywhere tcp dpt:domain
ACCEPT udp -- anywhere anywhere udp dpt:bootps
ACCEPT tcp -- anywhere anywhere tcp dpt:67
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere 192.168.122.2
ACCEPT all -- anywhere 192.168.122.0/24 ctstate RELATED,ESTABLISHED
ACCEPT all -- 192.168.122.0/24 anywhere
ACCEPT all -- anywhere anywhere
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT udp -- anywhere anywhere udp dpt:bootpc
# qemu-system-x86_64 --version
QEMU emulator version 3.1.0 (Debian 1:3.1+dfsg-2ubuntu3.3)
Copyright (c) 2003-2018 Fabrice Bellard and the QEMU Project developers
# libvirtd --version
libvirtd (libvirt) 5.0.0
我该如何修复端口转发问题?
答案1
如果您在主机系统上运行 telnet,则应扩展规则。要重定向本地发起的数据包,您应该将 DNAT 规则添加到链中nat/OUTPUT
。在您的案例中,您应该在相应条件(启动或重新连接)下添加以下行:
/sbin/iptables -t nat -I OUTPUT -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
还可以添加相反的命令来删除该规则。
/sbin/iptables -t nat -D OUTPUT -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
要列出带有计数器的完整规则集,最好使用命令iptables-save -c
而不是iptables
默认仅显示过滤表的命令。
答案2
我弄清楚了这个问题,结果发现我需要运行iptables -t nat -A POSTROUTING -j MASQUERADE
。
现在它起作用了!