QEMU / KVM - 每个虚拟机专用的 802.1q VLAN - 仅通过路由器进行通信

QEMU / KVM - 每个虚拟机专用的 802.1q VLAN - 仅通过路由器进行通信

我有一个 Linux 防火墙路由器(专用机器),有多个 eth接口(我的“大防火墙”)。所有转发的流量都由一组iptables规则进行过滤(默认策略为 DROP)。

还有另一台专用机器(“vmhost”)将使用 KVM / QEMU / libvirt / virsh 托管多个虚拟机。

防火墙路由器(物理服务器)和 vm 主机(另一台物理服务器)通过跳线直接连接(路由器的 eth2 <-> vmhost 的 eth0)。

我不希望 vmhost 上的虚拟机能够通信

  • 对彼此
  • 或虚拟机主机

除非通过外部防火墙路由器。

因此,我在两侧(路由器和 vmhost)配置了多个 802.1q 标记 VLAN:eth0.10、eth0.11 等(另一侧为 eth2.10、eth2.11 等),每个 VLAN 都有不同的/30子网(一个主机 IP = 路由器,另一个主机 IP = VM)。因此,每个 VM 都有自己的标记 VLAN 和自己的子网。

我想用这个来让虚拟机流量服从中央防火墙路由器的 iptables 规则。虚拟机只能访问明确允许的 IP 地址和端口。

如何配置虚拟机以使其绑定到专用 VLAN 接口(例如eth0.10)?关于net、、、...netdevnic

我明确地不想在虚拟机网络或虚拟机和主机之间建立桥接。

// 后来补充:两个服务器都使用 Debian 10 amd64。

答案1

一般有几种方法。注意,有些方法不允许您绕过桥接。配置是仍然安全尽管如此。

Linux 上桥接的基础知识如下,例如:https://developers.redhat.com/blog/2017/09/14/vlan-filter-support-on-bridge/

多座桥梁

这是一种老方法,在很老的 Linux 中可用,当时它同时支持桥接和 VLAN。它的缺点是配置相当混乱,但在某种程度上它更容易理解和管理。

您可以在主机上为每个 VLAN 子接口配置一个网桥,如下所示:

ip link add link eth0 name eth0.100 type vlan id 100
ip link set eth0.100 up
ip link add br100 type bridge
ip link set br100 up
ip link set eth0.100 master br100

依此类推。之后,如果您将虚拟机虚拟网卡放入其中br100,其未标记的数据包将出现在标记为 VLAN 100 的 eth0 之外,反之亦然,标记为 VLAN100 的数据包将到达此虚拟机。您在 vNIC 设置中将此网桥指定到虚拟机域文件中。要将虚拟机放入多个 VLAN,请为每个 VLAN 创建专用的虚拟网卡。

如果您不启用“bridge vlan_filtering”,Proxmox VE 也会使用此方法。您没有指定在哪个发行版上运行 libvirt,因此我无法建议您如何在特定情况下实现此配置。您可以看到它在 Debian 上的样子这里

原则上,您可以使用“未标记的默认”VLAN 来管理主机。我不推荐这样做,因为这样您将无法通过此 VLAN 进入任何虚拟机(不要将主节点eth0放入任何网桥!)。更好的方法是定义一个管理 VLAN,为其创建一个网桥,并将 IP 地址应用于主机上的管理网桥。假设此 VLAN 100 用于管理:

ip address add address 192.168.100.100/24 dev br100

单桥

这是一种“新”方法,一旦 Linux 桥接代码支持 VLAN 过滤,即可使用。它的主要优点是使 Linux 成为真正的 L2 交换机,配置不那么混乱 - 您只有一个桥接器。当启用“bridge vlan_filtering”时,Proxmox VE 直接支持它。

很遗憾,libvirt 不直接支持这种方法根据他们的手册。我不知道为什么,他们似乎很懒,因为内核中的所有内容都在那里。我会在这里记录下来,希望他们最终会支持它。

您创建了一座桥:

ip link add br0 type bridge vlan_filtering 1
ip link set br0 up
ip link set enp0s1 master br0

现在添加 VLAN 并定义哪些是带标签的,哪些是未带标签的。请记住,br0既是桥接器的名称,也是该桥接器通向主机的端口名称。因此,您可能希望在该主机上设置未带标签的管理 VLAN,该 VLAN 带标签enp0s1或未带标签;对于这种设置来说,这不会有问题。我们假设它的 ID 是 100,并且它在线路上带标签:

bridge vlan add vid 100 dev br0 pvid untagged
bridge vlan add vid 100 dev enp0s1
ip addr add 192.168.100.100/24 dev br0

现在带有 IP 地址的数据包将从带有标签 100 的 enp0s1 出去。

所有 VM vNIC 都将连接到此桥。但是,现在您需要设置哪些 VLAN 位于何处。同样,libvirt 不知道如何执行此操作。您需要将它们的 VLAN 添加到物理接口(我希望是带标记的),并添加到 vNIC 接口(带标记或不带标记,随您选择)。您必须手动执行此操作,就像对管理接口执行的操作一样。您可以将多个 VLAN 传递到同一个 vNIC,只需确保其中不超过一个未带标记。

其他方法

其他方法包括

开放VSwitch— libvirt 直接支持 vlan,但我不喜欢它,我认为它过于复杂。

真空泵— 一个好方法,支持在 libvirt 域文件中正确设置 VLAN,可以准确捕获您想要的内容。我不得不推荐我已经尝试过,但我从未用 VLAN 配置过,所以我不能。也许其他人尝试过并会详细解释。一般来说,它具有与“单桥”相同的便利性,只是 VM 之间或 VM 与主机之间的通信将不可能即使需要这样做,即使它们位于同一个 VLAN 中。

答案2

考虑一下:

  1. bond从真实接口创建 LACP eth- 即使您只有 1 个接口,这也为进一步提高速度和可靠性提供了空间
  2. 创建bridge包含该内容的bond文件VLANFiltering=no- 这将允许随时连接 OpenVPN 和其他功能,而无需担心
  3. vlan为主机操作系统创建bridge(我个人不喜欢混合标记和未标记的流量)
  4. 创建多个veth接口(充当电缆的接口对,允许在单个桥上创建相同的 VLAN,例如当 VM 与主机位于同一网络中时),将该对的main接口(或leader或)添加到masterbridge
  5. 创建vlanveth peerfollowerslave)并将其vlan用作macvtap接口virt-manager

…重复特定步骤…

利润

当使用 systemd-networkd 时,这将需要创建多个networknetdevlink文件。

也许可以使用VLANFiltering=yes并设置每个接口上的 VLAN IDveth main来减少不必要的流量,从而减少 CPU 负载。但我不确定。

参考:

https://www.freedesktop.org/software/systemd/man/latest/systemd.network.html

https://www.freedesktop.org/software/systemd/man/latest/systemd.netdev.html

https://www.freedesktop.org/software/systemd/man/latest/systemd.link.html

注意:在link实际接口文件中使用

[Match]
Property="ID_NET_NAME_MAC=****"

[Link]
Name=eth1-for-host
MACAddressPolicy=persistent

使其名称持久且人性化

相关内容