KVM 端口转发从 ppp0 到 VM 的桥接 NIC 不起作用,但是到 VM 的 NAT NIC 起作用吗?

KVM 端口转发从 ppp0 到 VM 的桥接 NIC 不起作用,但是到 VM 的 NAT NIC 起作用吗?

我花了很多时间在这个奇怪的问题上,我创建了一个简单的主机和虚拟机配置来尝试隔离该问题。

本问题中的术语

  • 主机:裸机服务器
  • VM:KVM 客户虚拟机
  • 到 ppp0 的传入连接:从具有不同互联网 IP 的单独互联网连接进行测试。

主机上已启用端口转发

root@host $ sysctl net/ipv4/conf/all/forwarding net.ipv4.conf.all.forwarding = 1

网络设置

  • 主机 eth0:10.0.0.155
  • 主机 ppp0:(互联网 IP)
  • VM 桥接适配器:10.0.0.121
  • VM NAT 适配器:192.168.122.126
  • 虚拟机正在监听 TCP0.0.0.0:10003

我想解决哪些不起作用的问题(主要目标)

主机端口 10003 上的传入连接应从 ppp0 转发到 VM 的桥接适配器。iptables-save -c 显示所使用的配置和计数器。 http://codepad.org/SWzL5kEy

什么有效

  • 主机可以通过其任一接口上的端口 10003 连接到虚拟机: root@host $ nc -z 192.168.122.126 10003; echo $? 0 root@host $ nc -z 10.0.0.121 10003; echo $? 0

  • 网络上的其他 PC 可以连接到虚拟机的桥接适配器 user@otherPConLAN $ nc -z 10.0.0.121 10003; echo $? 0

  • 主机端口 10003 上的传入连接已成功从 ppp0 转发到 VM 的 NAT 适配器。iptables-save -c 显示所使用的配置和计数器。 http://codepad.org/fwd3R7rF

  • 网络上的每个节点(包括主机、虚拟机和其他 PC)都可以相互 ping 通。

iptables-save -c 输出的区别

在显示 iptables-save -c 输出的两个浏览器选项卡之间切换,我看到配置是相同的。触发了相同的计数器。但主要的重要区别是,当成功建立与 NAT 适配器的连接时,第 32 行的 FORWARD 规则的计数高于与桥接适配器的连接失败时。

我的理论

我的理论是某种类型的 NAT 执行不正确,数据可能正在移动到 VM,但无法找到通过主机返回并从 ppp0 到客户端的路径。

VM 的 .xml 文件中的 NIC 配置

<interface type='bridge'> <mac address='11:11:11:11:11:11'/> <source bridge='br0'/> <model type='virtio'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface> <interface type='network'> <mac address='22:22:22:22:22:22'/> <source network='default'/> <model type='virtio'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> </interface>

桥梁状态

root@host $ brctl show bridge name bridge id STP enabled interfaces br0 8000.(obfuscated) no eth0 vnet0 virbr0 8000.(obfuscated) yes vnet1

TRACE 输出

以下是两种场景的 TRACE 输出。为了使 TRACE 输出简短且匿名,主机的互联网 IP 已替换为“hi”,测试客户端的互联网 IP 已替换为“ci”。

为 TRACE 添加了以下 IPTABLES 规则

root@host $ iptables -t raw -A PREROUTING -p tcp --dport 10003 -j TRACE root@host $ iptables -t raw -A OUTPUT -p tcp --dport 10003 -j TRACE

客户端运行了这个命令 user@remoteClient $ nc -z (host's internet IP) 10003; echo $?

当客户端无法连接到桥接适配器时运行此跟踪输出 http://codepad.org/FC9BhF7y

当客户端成功连接到 NAT 适配器时,运行此跟踪输出 http://codepad.org/0uHpXXzZ

相关内容