我有一个 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
、、、...netdev
nic
我明确地不想在虚拟机网络或虚拟机和主机之间建立桥接。
// 后来补充:两个服务器都使用 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
考虑一下:
bond
从真实接口创建 LACPeth
- 即使您只有 1 个接口,这也为进一步提高速度和可靠性提供了空间- 创建
bridge
包含该内容的bond
文件VLANFiltering=no
- 这将允许随时连接 OpenVPN 和其他功能,而无需担心 vlan
为主机操作系统创建bridge
(我个人不喜欢混合标记和未标记的流量)- 创建多个
veth
接口(充当电缆的接口对,允许在单个桥上创建相同的 VLAN,例如当 VM 与主机位于同一网络中时),将该对的main
接口(或leader
或)添加到master
bridge
- 创建
vlan
(veth
peer
或follower
或slave
)并将其vlan
用作macvtap
接口virt-manager
…重复特定步骤…
利润
当使用 systemd-networkd 时,这将需要创建多个network
、netdev
和link
文件。
也许可以使用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
使其名称持久且人性化