Qemu VM 连接局域网主要有两种方式:type=user
或type=tap
。该user
模式完全隔离专用网络中的虚拟机,将其通过 NAT 托管到主网络堆栈。使用tap
比较复杂,需要一个virtual来成为物理接口( )和虚拟接口( )bridge
的master 。这就像数据从外部世界和主机流向虚拟机的管道。我花了很多时间尝试调节主机端接口上的网络流量/将所有 http 请求重定向到某个内部 IP 地址,但没有成功。所有建议、论坛和 wiki 都推荐了大量解决方案,但这些解决方案不起作用,主要原因是:来自 VM guest 虚拟机的数据包永远不会到达主机内核网络堆栈。如果 IP 主机地址不是它们的目标,它们会在网桥级别选择自己的方式,并且不满足由任何数据包过滤器链调整的任何防火墙规则。您可以简单地通过将主机全局策略设置为(使用主机 XYtables)来尝试,您可以看到:主机网络完全失效,但来宾可以继续通过网络发送和接收数据包。eth0
tap0
tap0
tap0
iptables
nftables
DROP
好吧,问题是:是否有其他方法,如何将 VM 来宾虚拟连接到主机虚拟网络接口?为了更好地理解图表如下:
General virtual connections for host/VM guest
+---------------------------------------------+
| +-----------------------------+ |
| | iptables host kernel | |
| | nftables network stack | |
| +-------+---------------------+ |
| | |
| +-------+---------+ +-----------+ |
---eth0--+ virtual | | VM | |
| | bridge +-tap-eth0 guest | |
---eth1--+ br0 | | | |
| +-----------------+ +-----------+ |
+---------------------------------------------+
Host became a router for VM guest
+-------------------------------------+
| +----------------+ +---------+ |
---eth0--> host kernel | | VM | |
| | <-vppp guest | |
---eth1--> network stack | | | |
| +----------------+ +---------+ |
+-------------------------------------+
为了解决我的问题,必须找到一种方法来控制(例如使用nftables)虚拟桥本身的流量,或者如何通过虚拟线路将VM来宾网络接口连接到主机的虚拟网络接口。类似于 PPPoE 网络。
但最终也是最清晰的方法是向 Qemu 用户模式网络添加更多参数,以便能够强制将某些端口(服务)重定向到选定的目标地址,包括主机环回。是的,我向 Qemu 团队发送了这样的愿望,并得到了答案:这不是最重要的功能。
答案1
有两种可能的解决方案:
- 使用 nftables
bridge
系列并在第 3 层以下进行过滤。 - 将主机用作路由器。
第一个解决方案是更有效的选项,但限制您过滤以太网帧的属性。您无法过滤 IP 地址或端口,或第 3 层或更高层的任何其他内容,因为网桥不处理任何此类数据。
第二种解决方案更有可能让您在这里做您想做的事情。这实际上是非常简单有两个具体原因:
- 您可以直接在桥接接口上分配 IP 地址,就像任何其他网络设备类型一样。
- 您不需要将任何物理网络设备连接到桥接接口。
给出这个,您想要做的“正常”设置是:
- 在主机系统上设置桥接接口。为其分配静态 IP,但不要将其连接到任何物理接口。
- 配置 nftables,以便系统处理步骤 1 中的桥接接口与任何外部接口之间的路由。
- 启动 VM 时,将其连接到步骤 1 中的桥接口。
然后,您只需过滤 nftables 中的内容,与系统充当外围防火墙没有什么不同。您可以通过在主机系统上设置 DHCP 服务器和缓存 DNS 解析器来使这一过程变得更加容易,这样您就不需要为虚拟机提供静态网络配置。