Qemu 虚拟机连接局域网主要有两种方式:type=user
或type=tap
. 该user
模式将私有网络中的虚拟机完全隔离,通过 sNAT 托管主网络堆栈。使用tap
比较复杂,需要一个virtualbridge
成为master一个物理接口(eth0
)和虚拟接口(tap0
)。这tap0
就像一个管道,用于从外部世界和主机流向 VM 的数据。我花了很多时间试图调节tap0
主机端接口上的网络流量iptables
/nftables
例如将所有 http 请求重定向到某个内部 ip 地址,但没有成功。所有的建议、论坛和 wiki 都推荐了大量的解决方案,但这些解决方案都行不通,主要原因是:来自 VM guest 的数据包永远不会到达主机内核网络堆栈。如果 IP 主机地址不是他们的目标,他们会在网桥级别选择自己的方式,并且不满足任何数据包过滤器链调整的任何防火墙规则。您可以简单地通过将主机全局策略设置为 (with host XYtables) 来尝试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 团队表达了这样的愿望,并得到了答复:这不是最重要的功能。
有两种可能的解决方案:
bridge
系列并在第 3 层以下进行过滤。第一个解决方案是更有效的选择,但限制您过滤以太网帧的属性。您无法过滤 IP 地址或端口,或第 3 层或更高层的任何其他内容,因为网桥不处理任何此类数据。
第二种解决方案更有可能让你在这里做你想做的事。这实际上很简单,具体有两个原因:
给这个,你想做的“正常”设置是:
然后,您只需过滤 nftables 中的内容,就像系统充当外围防火墙一样。您可以通过在主机系统上设置 DHCP 服务器和缓存 DNS 解析器来简化此操作,这样您就不需要为 VM 提供静态网络配置。