如何使用未标记的入口数据包和标记的出口数据包创建 Linux VLAN 感知桥

如何使用未标记的入口数据包和标记的出口数据包创建 Linux VLAN 感知桥

我正在尝试对与我在实际案例场景中观察到的交换机配置错误相关的特定问题实施一种晦涩的解决方法。

请假设以下情况:

  • 我的系统通过思科交换机插入主干链路;
  • 我可以在特定 VLAN(不是本机 VLAN)中发送标记数据包,它将被正确路由到正确的 VLAN;
  • 我收到作为未标记流量的响应,即使它位于中继上并且来自非本机 VLAN ;
  • 我无法修改交换机的配置。

我正在尝试执行的是一种在 Debian 上使用单个网络接口的方法,在该接口中我可以正确发送和接收流量以将流量插入所需的 VLAN,即使数据包必须被标记出去并且将被捕获而不加标记。

举个例子,可以使用 ICMP 回显请求 ping 远程系统。使用我的简单 eth0 接口不会有任何效果,不会看到 ICMP 回显回复。但是,如果我在 VLAN 10 中标记 ICMP 回显请求,我将收到未标记的 ICMP 回显回复!例如,它也可以与 DHCP 一起使用(远程网络确实有一个 DHCP 服务器)。如果我发送标记的 DHCP 发现数据包,我将收到带有相应事务 ID 的未标记的 DHCP Offer。

我知道这不是正常行为,最终可能会导致数据包被错误路由或被错误地假定位于 VLAN 中。这是由于交换机配置错误(我认为这与某处本地 vlan 不匹配有关)。

如果我使用 vlan 子接口(ip link add link type vlan ...),我将发送标记的流量,但响应永远不会从主接口路由回子接口,因为它期望流量被标记回来。

然后我发现了 vlan 感知网桥,它看起来像是解决我的问题的正确解决方案,尽管我没有成功地使用网桥 vlan 添加命令(pvid、vid、未标记或不,我是否需要使用 vlan 子接口)来成功执行此操作?)。

我一次只需对一个 VLAN 执行此操作。由于标签丢失,将无法确定数据包发送到哪个 VLAN。但是,我可以根据 IP 地址、STP 和 CDP 流量推断出此 VLAN 标记。我不想做任何自动化的事情,我不想猜测 VLAN,我只是希望能够强制未标记的流量被视为位于选定的任意 VLAN 中,一次一个。

谢谢 !

答案1

简介/初始设置

此答案并不尝试将下面使用的命令集成到网络配置工具中。至少以下工具预计可用于此目的,而无需额外的命令:

VLAN 感知桥接接口可以通过使用端口 VLAN ID (PVID) 来修复像这样错误配置的单个 VLAN。即使使用单个桥接端口,它也将仅用作取消外部错​​误配置的层。

由于没有提供初始配置来进行构建,因此我使用了 VLAN 10 和在此 VLAN 中使用的 IP 地址 192.0.2.2/24 的示例,以及接口以太网0。考虑初始配置如下:

ip link set dev eth0 up
ip link add link eth0 name eth0.10 up type vlan id 10
ip addr add dev eth0.10 192.0.2.2/24 # or use DHCP
ip route add default via 192.0.2.1 dev eth0.10

由于OP当前的情况,这不会起作用,因为网络堆栈(例如:在以太网0并在预期时被忽略eth0.10)或其他组件(使用原始套接字在未侦听的接口上接收回复的 DHCP 客户端)将忽略返回流量,因为(由于外部错误)它不是同一接口(未标记)以太网0,而不是标记的以太网0<=> 未标记eth0.10)。

使用 VLAN 感知网桥代替

可以做的是将 VLAN 接口的使用替换为具有单个网桥端口的 VLAN 感知网桥(以太网0)。现在可以在网桥上动态配置 VLAN 标记和端口 VLAN ID,而无需创建/删除 VLAN 接口。适当的配置将消除远程错误配置。

  • 清理之前的状态(警告:连接丢失)

    ip link del dev eth0.10
    
  • 创建 VLAN 感知网桥

    ip link add name br0 type bridge vlan_filtering 1 vlan_default_pvid 0
    

    上面vlan_filtering 1创建了支持 VLAN 的网桥,并vlan_default_pvid 0使其默认不使用 VLAN,因此无需先删除任何地方未使用的 VLAN。必须显式添加 VLAN 才能启动实际的网桥通信。

  • 可选:(主要用于基于MAC的DHCP服务器配置保持相同的地址)复制以太网0的 MAC 地址为br0

    ... 因为该地址不会在最近的任何系统环境。在的帮助下jq可以复制的命令以太网0的 MAC 地址为br0。这应该在设置之前完成以太网0作为桥接端口。

    ip link set dev br0 address "$(ip -json link show dev eth0 | jq -r '.[].address')"
    
  • 将 eth0 设置为桥接端口并设置桥接:

    ip link set dev eth0 master br0
    ip link set br0 up
    
  • 将网桥接口本身配置为链接到路由堆栈的网桥的唯一部分,为未标记和 PVID 10:路由堆栈不处理 VLAN 帧,仅处理 IP(和 ARP)帧,因此请确保不发出标记帧或预期。

    过时的brctl命令无法处理 VLAN 感知网桥。这需要bridge vlan ...命令已经由ip路由2套房。当它涉及桥接接口本身而不是桥接端口时,self需要附加关键字。

    bridge vlan add vid 10 dev br0 pvid untagged self
    
  • 添加桥接端口以太网0作为(标记的)VLAN 10,但也作为 PVID:因此它将发出标记帧,并接受两个标记帧(仅 VLAN 10),并将未标记帧视为 VLAN 10 帧:无论交换机是否配置错误,都将工作。

    bridge vlan add vid 10 dev eth0 pvid
    

    或者,让网桥首先接受所有标记的 VLAN,然后仅更改 VLAN 10 的配置。这在当前配置中没有用处,但如果将其他网桥端口添加到其他地方的网桥流量,则会很有用。那将是:

    bridge vlan add vid 2-4094 dev eth0
    bridge vlan add vid 10 dev eth0 pvid
    

    这会得到:

    # bridge -compressvlans vlan show
    port              vlan-id  
    eth0              2-9
                      10 PVID
                      11-4094
    br0               10 PVID Egress Untagged
    

现在这将解决错误配置并允许正常使用br0作为主接口,例如通过在其上配置静态地址,预计将允许通信:

ip addr add 192.0.2.2/24 dev br0
ip route add default via 192.0.2.1

或者通过运行 DHCP 客户端br0来配置它。

要更改要收听的 VLAN,例如从 VLAN 10 更改为 VLAN 11:

  • 重新配置桥接口br0

    bridge vlan del vid 10 dev br0 self
    bridge vlan add vid 11 dev br0 pvid untagged self
    
  • 重新配置桥接端口以太网0

    bridge vlan del vid 10 dev eth0
    bridge vlan add vid 11 dev eth0 pvid
    

    如果相反,必须接收所有 VLAN,因为每个端口只有一个 PVID,请将其切换到 VLAN 11,而不删除 VLAN 10:

    bridge vlan add vid 11 dev eth0 pvid
    

笔记

  • 这个答案是通过使用 Linux VLAN 感知网桥(系统侧网桥端口位于 VLAN 10 上)模拟配置错误的交换机来测试的但也未标记
  • 由于现在有一座新桥,如果模块出现问题,预计会出现问题br_netfilter已加载:在此系统上运行 Docker 可能需要其他解决方法。

相关内容