我们的目标
我们想要运行一个带有多个 QEMU VM 的服务器,其中一些 VM 应该连接到单独的 VLAN。主机通过绑定连接到交换机,并且应该有一个 VLAN 感知桥,所有 VM 都连接到该桥(就像一个带有 VLAN 的真实交换机,但采用软件方式)。桥本身被分配了主机的 IP,并且该主机应该能够访问 VM。为了保护主机/桥/主 LAN,应该使用 iptables(VM 之外的 iptables)过滤主机上的一些 VM 接口(传入和传出)。
我们的设置
测试服务器是一台具有 4 个端口和 Ubuntu 20.4 服务器的 Supermicro 机器。它连接到一个小型 Zyxel GS-1900 交换机,而该交换机又连接到我们的 LAN 网络(HP 基础设施)。我们从 PVID 1 和已经在堆栈和 WLAN AP 上设置的 VLAN 55 开始。交换机端口设置了 PVID 1 和标记的 VLAN 55。在物理网络上一切都应该正常。对于测试,我甚至没有设置虚拟机,它只是一个普通的操作系统,我将 VLAN 55 中的 IP 分配给 VLAN 接口。我们没有使用 netplan、NetworkManager 或 systemd 配置。我们只使用 /etc/network/interfaces。
我们的问题
我无法让具有 VLAN 感知桥的 Ubuntu 主机与 VLAN 配合使用。ping VLAN 55 导致 ARP who-has - 就是这样。我可以在 VLAN 接口 (tcpdump) 上看到它,但在任何其他接口上都看不到它。为什么 ARP 无法通过?如果 ARP 可以通过,其余的会正常工作吗?
我们做了什么
我们手动尝试了所有方法,但根本不知道我们错过了什么。我们甚至重新安装了机器。我们陷入困境。
这些是命令我们认为这应该有效。但事实并非如此:
ip link add bond0 type bond
ip link set bond0 type bond miimon 100 mode balance-alb
ip link set eth0 down
ip link set eth0 master bond0
ip link set bond0 up
ip link add br0 type bridge
ip link set br0 up
ip link set br0 type bridge vlan_filtering 1
ip link set bond0 master br0
ip link add venet0 type veth peer venet0_0
ip link set venet0 master br0
bridge vlan add dev venet0 vid 55 master
bridge vlan del dev venet0 vid 1
bridge vlan add dev bond0 vid 55
ip address add dev venet0_0 192.168.55.0/24
ip address add dev br0 10.233.202.2/22
ip link set venet0 up
ip link set venet0_0 up
我们没有看到任何错误,结果看起来我们认为是正确的。br0 接口可以 ping 本地 VLAN 55 接口,如果设置了默认 gw,它可以 ping 到外部世界。但是 VLAN 接口除了自己之外无法 ping 任何东西。问题是没有 arp 响应,因为在任何其他端口上都看不到 arp。
输出ip 链接显示是:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc mq master bond0 state UP mode DEFAULT group default qlen 1000
link/ether 3c:ec:ef:33:8a:74 brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 3c:ec:ef:33:8a:75 brd ff:ff:ff:ff:ff:ff
4: eth2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 3c:ec:ef:33:8a:76 brd ff:ff:ff:ff:ff:ff
5: eth3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 3c:ec:ef:33:8a:77 brd ff:ff:ff:ff:ff:ff
15: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP mode DEFAULT group default qlen 1000
link/ether 3c:ec:ef:33:8a:74 brd ff:ff:ff:ff:ff:ff
16: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether 3c:ec:ef:33:8a:74 brd ff:ff:ff:ff:ff:ff
inet 10.233.202.2/22 scope global br0
valid_lft forever preferred_lft forever
17: venet0_0@venet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether de:d7:d5:3c:ed:91 brd ff:ff:ff:ff:ff:ff
inet 192.168.55.5/24 scope global venet0_0
valid_lft forever preferred_lft forever
18: venet0@venet0_0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP mode DEFAULT group default qlen 1000
link/ether 72:48:95:e5:9a:47 brd ff:ff:ff:ff:ff:ff
输出桥接 VLAN 显示:
port vlan ids
bond0 1 PVID Egress Untagged
55
br0 1 PVID Egress Untagged
venet0 55 Egress Untagged
路线-n显示:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.233.202.0 0.0.0.0 255.255.252.0 U 0 0 0 br0
192.168.55.0 0.0.0.0 255.255.255.0 U 0 0 0 venet0_0
和tcpdump -nlpvvvi venet0_0显示(.254 可通过物理交换机使用):
14:38:47.657112 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 192.168.55.254 tell 192.168.55.5, length 28
上面显示的配置在互联网上的几个地方都可以找到,并且报告说可以正常工作。我们在这里做错了什么?
多谢!
编辑:
a. 在 tcpdump 中,我刚刚看到一个数据包从接入点进入 venet0_0,表明客户端已漫游。奇怪...
b. 添加了以下非常简单的图片
编辑2-解决方案:
ip link add bond0 type bond
ip link set bond0 type bond miimon 100 mode balance-alb
ip link set eth0 master bond0
ip link set bond0 up
ip link add br0 type bridge
ip link set br0 up
ip link set br0 type bridge vlan_filtering 1
ip link set bond0 master br0
ip link add venet0 type veth peer venet0_0
ip link set venet0 master br0
bridge vlan add dev venet0 vid 55 untagged pvid
bridge vlan del dev venet0 vid 1
bridge vlan add dev bond0 vid 55 master
ip link set venet0 up
ip link set venet0_0 up
这最终在 /etc/network/interfaces 中使用
感谢 Nikita Kipriyanov
编辑 3-/etc/network/interfaces
这是我根据这个制作的 /etc/network/interfaces 部分。关于 Nikita 的评论,似乎可以在没有所有 post-up 节和命令的情况下编写文件。我只知道来自 vconfig/vlan 的旧符号 ethY.XX,我不确定这如何与新的桥接命令配合使用;这就是我使用所有 post-up/pre-down 的原因。以下是接口文件:
auto eth0
iface eth0 inet manual
bond-master bond0
auto eth1
iface eth1 inet manual
bond-master bond0
auto bond0
iface bond0 inet manual
bond-slaves eth0 eth1
bond-mode balance-xor
bond-miimon 100
bond-updelay 200
bond-downdelay 200
bond-xmit-hash-policy layer3+4
auto br0
iface br0 inet static
bridge_ports bond0
bridge_stp on
bridge_vlan_aware yes
address 10.233.202.2/22
gateway 10.233.200.254
post-up ip link set br0 type bridge vlan_filtering 1
post-up ip link set br0 type bridge nf_call_iptables 1
post-up ip link set br0 type bridge nf_call_ip6tables 1
post-up ip link set br0 type bridge nf_call_arptables 1
post-up ip link add br0p1 type veth peer br0p1c
post-up ip link set br0p1 master br0
post-up bridge vlan del dev br0p1 vid 1
post-up bridge vlan add dev br0p1 vid 55 untagged pvid
post-up bridge vlan add dev bond0 vid 55
pre-down bridge vlan del dev bond0 vid 55
pre-down ip link del dev br0p1
auto br0p1
iface br0p1 inet manual
对于 vlan 接口上的 iptables,使用 -m physdev 执行
modprobe br_netfilter
和
echo 1 >/proc/sys/net/bridge/bridge-nf-filter-vlan-tagged
答案1
您缺少桥接端口上 VLAN 55 的“PVID”设置venet0
。它未显示在 中bridge vlan show
。
您将此标签设置为出口,这意味着离开系统到此接口的任何未标记数据包都将被标记为 VLAN 55。缺失的物理安全ID设置执行相反的操作:它告诉系统剥离 VLAN 标记 55 并在没有标记的情况下呈现给系统。目前,它不会执行此标记剥离操作。
要验证这一点,请使用当前配置,使用附加开关重新运行 tcpdump 命令-e
(显示以太网信息)。它应该显示您从该接口看到的数据包仍然带有标记;这就是 Linux 忽略它们的原因。
是的,您可能已经猜到了,Linux 能够实现非对称 VLAN。
为了启用正确的标签处理(使事情对称 - 这是你所期望的),使用
bridge vlan add dev venet0 vid 55 untagged pvid
而不是你的bridge vlan add dev venet0 vid 55 master
。
此外,/etc/network/interfaces
Debian 网络脚本允许比您通过输入这一组命令获得的配置更加模块化的配置。它本身能够创建绑定、VLAN、网桥(包括可识别 VLAN 的网桥)。最好使用它,不要将这个糟糕的脚本放在原始位置,它违背了网络初始化系统的目的!