Linux 中的 VLAN 支持

作者:Henry Van Styn

Linux 成为出色的路由器和防火墙,这并不令人惊讶。一个不太为人所知的事实是,您还可以将 Linux 用作以太网桥接器和 VLAN 交换机,并且这些功能同样强大、成熟和完善。正如 Linux 可以完成 PIX 或 SonicWall 可以做的任何事情一样,它也可以完成托管 VLAN“智能交换机”可以做的任何事情——甚至更多。

为什么要使用 VLAN?

当您听到 VLAN 这个术语时,可能会想到大型企业或园区网络。减轻维护这些类型网络的负担是最初开发 VLAN 技术的主要原因之一。

VLAN 允许按需重新安排网络拓扑——纯粹在软件中——而无需移动物理电缆。VLAN 还允许多个独立的第 2 层网络共享同一物理链路,从而实现更灵活且更具成本效益的布线布局。VLAN 让您事半功倍。

以具有多个 LAN 和数据机房的大型分散网络为例。如果没有 VLAN 的好处,将设备移动到新 LAN 的唯一方法是它是否可以在与旧 LAN 相同的数据机房(设备连接的位置)中访问。如果不是,您别无选择,只能拉一根新电缆或将设备物理移动到可以访问新 LAN 的位置。但是,使用 VLAN,这只是一个简单的配置更改。

这些是通常与 VLAN 相关的优势和应用类型,但除了这些之外,还有更多适用于所有规模网络(甚至小型网络)的场景。

由于 VLAN 交换机在历史上一直很昂贵,因此它们的使用仅限于较大的网络和较大的预算。但是近年来,随着 Netgear 和 Linksys 等品牌进入市场,价格已经下降,可用性也随之提高。

如今,VLAN 交换机很便宜(不到 100 美元),并且开始变得司空见惯。我怀疑再过几年,就很难找到没有 VLAN 支持的交换机了,就像今天很难找到“集线器”一样。

在本文中,我将简要概述 802.1Q VLAN 技术和配置,然后解释如何配置 Linux 以直接与 VLAN 拓扑接口。我将描述 VLAN 交换机如何帮助您向 Linux 盒添加虚拟以太网接口,从而节省您购买硬件甚至重新启动的需要。我还将研究解决其中一些小规模网络烦恼。您是否认为您的 Linux 防火墙必须位于 Internet 连接附近并具有两个网卡?请继续阅读。

802.1Q VLAN 基础知识

VLAN(虚拟 LAN)的目的是从各个端口而不是整个交换机构建 LAN。VLAN 配置可以像单个交换机上的端口分组一样简单。交换机只是阻止单独组(VLAN)的端口相互通信。这与拥有两个、三个或更多个未连接的交换机没有什么不同,但您只需要一个物理交换机,并且由您决定如何在“虚拟交换机”之间分配端口(这里三个端口,那里八个端口等等)。

当您想将此概念扩展到多个交换机时,事情会变得更加复杂。交换机需要一种标准方法来协作并跟踪哪些流量属于哪个 VLAN。目的仍然相同——从各个端口而不是整个交换机构建 LAN,即使端口分布在多个交换机甚至多个地理位置。

IEEE 802.1Q

尽管各种制造商最初创建了其他专有的 VLAN 格式,但当今使用的主要标准是 802.1Q。简而言之,802.1Q 提供了一种简单的方法,供多个 VLAN 交换机通过将 VLAN 特定的数据直接附加到各个以太网数据包的标头来协作。

IEEE 802.1Q 是一项开放标准,这意味着,从理论上讲,所有兼容设备都可以互操作,而与制造商无关。Linux VLAN 基于 802.1Q,几乎任何宣传“VLAN”的交换机都将支持此标准。

您可以将 VLAN 交换机视为以太网设备的自然演进,其祖先是交换机和集线器。交换机和集线器之间的根本区别在于交换机可以做出决策。它不会将数据包发送到它知道找不到目标 MAC 的端口。交换机会在实时处理数据包时自动了解有效的端口/MAC 映射(并将该信息存储在其“ARP 缓存”中)。

VLAN 交换机在此基础上增加了另一个条件。它不会将数据包发送到不属于数据包所属 VLAN 的端口(“出口端口”或接收器)。这基于数据包的 VLAN ID (VID),VID 是介于 1 和 4096 之间的数字。

如果数据包还没有 VID,则会根据其到达端口(“入口端口”或源)为其分配一个 VID。这是端口的主要 VID (PVID)。每个交换机端口都可以是多个 VLAN 的成员,其中一个必须配置为其 PVID。

VID 存储在添加到数据包的额外的 4 字节标头中,称为标记。向数据包添加标记称为标记。只有 VLAN 设备知道如何处理标记的数据包;普通的以太网设备不希望看到它们。除非数据包被发送到另一个 VLAN 交换机,否则在发送之前需要删除标记。此取消标记是在交换机确定出口端口后完成的。

如果端口连接到另一个 VLAN 交换机,则需要保留标记,以便下一个交换机可以识别数据包的 VLAN 并相应地处理它们。当数据包必须跨越 VLAN 中的多个交换机时,所有后续交换机都依赖于第一个接收数据包的交换机分配给数据包的 VID。

注意

在仅具有单个交换机的 VLAN 的情况下,不应发送或接收标记的数据包。但是,将标记和取消标记视为正在发生仍然很有用

  • 数据包到达并根据入口端口的 PVID 进行标记。

  • 根据标记中的 VID 确定出口端口。

  • 数据包被取消标记并发送。

所有数据包在进入网络时都以未标记状态开始,并且当它们离开网络并到达目的地时也应始终以未标记状态结束。在它们的旅程中,如果它们穿过 VLAN 网络,它们将被标记上 VID,由一个或多个 VLAN 交换机根据此 VID 进行交换,然后最终由最后一个 VLAN 交换机取消标记。

如果您一直在关注,您就会知道您需要为每个交换机的每个端口配置三件事

  • 成员 VLAN(VID 列表)。

  • PVID(必须是成员 VLAN 之一)。

  • 数据包在发送时(出口)应保持标记还是取消标记。

使用一个或多个交换机,您可以通过选择性地配置每个端口上的上述三个设置来实现任何 VLAN 拓扑。

Linux 作为交换机(又名网桥)

VLAN 交换机实际上只是具有一些扩展功能的普通交换机。在拥有 VLAN 交换机之前,您首先需要拥有普通交换机。幸运的是,Linux 已经完全支持这一点——只是不称为“交换”。

使 Linux 成为您所认为的“交换机”的功能称为桥接,这是一个更具体和准确的术语,因为它基于官方桥接标准 IEEE 802.1D。

在所有实际用途中,交换机和网桥都是相同的。交换机是行业创造的一个宽松术语,对于不同的产品意味着不同的含义(例如,10 美元的交换机通常不完全支持 802.1D,而 500 美元的交换机通常至少支持 802.1D,以及许多其他功能)。

802.1Q VLAN 交换机实际上是 VLAN 网桥,因为 802.1Q 作为标准只是扩展了 802.1D(所有支持 802.1Q 的设备也必须支持 802.1D)。从技术上讲,VLAN 网桥是正确的术语,但很少有人知道这意味着什么。

配置网桥

为了在 Linux 中使用网桥,您需要一个使用 CONFIG_BRIDGE 编译的内核和 userland 包 bridge-utils。我建议您还添加 ebtables 内核选项和 userland 工具。

将系统中的每个以太网接口都视为一个单端口交换机。以太网接口已经执行与交换机相同的基本功能——转发数据包、维护 ARP 缓存等等——但在一个端口上,无需或无法决定应将数据包发送到哪些其他端口。

Linux 的桥接代码通过允许您将网桥定义为捆绑一个或多个常规以太网接口的虚拟以太网接口,从而优雅地插入并扩展了现有功能。网桥中的每个接口都是一个端口。在操作中,这与交换机的端口完全相同。

用于管理网桥的 userland 工具是 brctl。以下是如何设置包含 eth0 和 eth1 的新网桥

brctl addbr br0
brctl addif eth0
brctl addif eth1
ip link set br0 up

运行这些命令后,您将拥有一个新的以太网接口,名为 br0,它是 eth0 和 eth1 的聚合。对于典型用法,您将不再在 eth0 和 eth1 上配置 IP 地址——您现在将改用 br0。

理解其工作原理的最佳方法是将 br0 想象成您盒子中的物理以太网接口,它插入到您桌子上的三端口交换机中。由于 br0 插入到其中一个端口,这将使交换机剩下两个剩余端口——eth0 和 eth1 是这两个交换机端口(图 1)。

VLAN Support in Linux

图 1. 由网桥创建的假想三端口交换机

数据包将在接口/端口之间传递,网桥将学习并维护 ARP 缓存,并且像交换机一样,它将决定应将每个数据包转发到哪些端口。

但是,与系统外部的普通交换机不同,您拥有并控制所有端口。您现在可以使用 Linux 下可用的任何和所有工具来创建终极托管交换机!

由于您仍然可以访问底层以太网接口,因此您可以执行诸如在端口上单独使用 tcpdump 或 snort 进行嗅探之类的操作。使用 ebtables 包,您可以像 iptables 对 IP 数据包一样,以相同的控制和精度过滤通过交换机的以太网数据包。

ebtables 等主题超出了本文的范围,但请参阅 ebtables 手册页和网站(请参阅资源)。

配置 VLAN 接口

VLAN 支持需要一个使用 CONFIG_VLAN_8021Q 编译的内核和 vlan userland 包(我建议您还启用 CONFIG_BRIDGE_EBT_VLAN,以便您可以在 ebtables 规则中匹配 VID)。

使用 vconfig 工具创建基于物理以太网接口和特定 VLAN ID 组合的虚拟 VLAN 接口。这些接口可以像系统上的任何其他以太网接口一样使用。

运行以下命令以添加与 eth0 和 VID 5 关联的新接口

vconfig add eth0 5
ip link set eth0.5 up

这将创建虚拟接口 eth0.5,它将具有以下特殊的 VLAN 特定行为

  • 从 eth0.5 发送的数据包将标记为 VID 5 并从 eth0 发送。

  • 在 eth0 上接收到的标记为 VID 5 的数据包将在 eth0.5 上显示为正常(即,未标记)数据包。

只有标记为 VID 5 的数据包才会到达虚拟 VLAN 接口。

整合所有内容

Linux 和现成的 VLAN 交换机之间的最大区别在于,Linux 可以作为网络上的主机参与,而不仅仅是为其他主机转发数据包。由于 Linux 盒本身可以是网络通信的终点,因此配置方法与典型的 VLAN 交换机不同。

每个端口/VID 组合不是为每个端口设置 VLAN 成员身份,而是获得自己的虚拟 eth 接口。通过添加这些接口并可选地将它们与物理接口桥接,您可以创建任何所需的 VLAN 配置。

Linux 中没有每端口 PVID 设置。它是根据物理入口接口桥接到哪个 VLAN 接口(或哪些 VLAN 接口)隐式确定的。如果要根据接口的 VID 在虚拟 VLAN 接口上发送数据包,则会对数据包进行标记。当数据包在给定网桥的物理接口和虚拟接口之间流动时,标记和取消标记操作会自动发生。请记住,PVID 设置仅在转发接收为未标记的数据包时才相关。

对于典型的 VLAN 交换机,只有一个网桥(交换机本身),每个端口都是其成员。流量分段是通过单独的每端口入口 (PVID) 和出口 VLAN 成员身份规则来实现的。由于 Linux 可以有多个网桥,因此 PVID 设置是不必要的。

这些细节只是约定俗成;有效配置在所有 VLAN 平台上仍然相同。这听起来比实际情况复杂。理解这一切的最佳方法是使用一些真实世界的示例。

加入现有 VLAN

假设您有一个带有单个物理接口 (eth0) 的 Linux 盒,您想将其加入到三个现有 VLAN:VID 10、20 和 30。首先,您需要验证现有交换机/端口的配置,您将把 Linux 盒插入其中。它需要是所有三个 VLAN 的成员,并为所有三个 VLAN 启用标记。接下来,在 Linux 盒上运行以下命令

ip link set eth0 up
vconfig add eth0 10
ip link set eth0.10 up
vconfig add eth0 20
ip link set eth0.20 up
vconfig add eth0 30
ip link set eth0.30 up

然后,您可以像使用普通接口一样使用 eth0.10、eth0.20 和 eth0.30(添加 IP 地址,运行 dhclient 等)。这些接口的行为将与连接到每个 VLAN 的普通物理接口完全相同。在此示例中只有一个物理接口,因此无需定义网桥。

扩展现有 VLAN

假设您想在上面的示例中使用 Linux 盒将非 VLAN 感知笔记本电脑连接到 VLAN 20。您需要添加另一个物理接口 (eth1),然后将其与 eth0.20 桥接。我将网桥命名为 vlan20,但您可以将其命名为任何名称

brctl addbr vlan20
ip link set vlan20 up
brctl addif vlan20 eth0.20
ip link set eth1 up
brctl addif vlan20 eth1

现在 eth1 是 VLAN 20 上的一个端口,您可以插入笔记本电脑(或整个交换机以连接多个设备)。通过 eth1 连接的任何设备都将 VLAN 20 视为普通以太网网络(未标记的数据包),如图 2 所示。

VLAN Support in Linux

图 2. 扩展 VLAN 配置

eth1 的隐含 PVID 为 20,因为它已与该虚拟 VLAN 接口桥接。您没有在 eth1 上创建任何 VLAN 接口(例如 eth1.20),因为您不希望它发送或接收标记的数据包。正是与 eth0.20 的网桥使 eth1 成为 VLAN 的“成员”。

与任何网桥配置一样,您还需要停止将 eth0.20 用作配置的接口,并开始使用 vlan20 代替它。

单接口防火墙

将 Linux 盒配置为防火墙/网关的典型配置是具有两个物理接口,一个连接到 Internet 路由器(公共侧),另一个连接到内部 LAN 交换机(私有侧),如图 3 所示。

VLAN Support in Linux

图 3. 典型的双接口防火墙配置

但是,如果 Internet 路由器和交换机/配线架位于布线间内,那里没有空间安装 Linux 盒,并且每个可能的放置位置只有一个插孔/电缆怎么办?

VLAN 使这不成问题。您可以安装小型现成的 VLAN 交换机(配置有两个 VLAN(VID 1 和 2)),而不是将 Linux 盒物理安装在公共网络和私有网络之间。

将一个端口配置为同时属于两个 VLAN 的成员,并启用标记。您会将 Linux 盒插入到此端口。这应该是唯一配置了标记的端口,因为它是唯一将与另一个 VLAN 设备(Linux 盒)通信的端口。所有其他端口都将设置为未标记。

将交换机的另一个端口配置为仅 VLAN 2 的成员(未标记,PVID 设置为 2)。您会将 Internet 路由器插入到此端口。

将其余端口保留在仅 VLAN 1 上(未标记,PVID 设置为 1)。这些是私有网络上所有主机的端口。如果主机多于端口,您可以将另一个交换机或多个交换机(非 VLAN)插入到这些 VLAN 1 端口中的任何一个,以服务于其余主机。

Linux 盒只需要一个物理接口 (eth0)。运行以下命令来配置 VLAN

ip link set eth0 up
vconfig add eth0 1
ip link set eth0.1 up
vconfig add eth0 2
ip link set eth0.2 up

就像在第一个示例中一样,您现在可以像往常一样配置 IP 地址和防火墙,使用 eth0.1 作为私有网络上的接口,eth0.2 作为公共网络上的接口(图 4)。

VLAN Support in Linux

图 4. 具有 VLAN 的单接口防火墙配置

与第一个示例一样,由于 Linux 盒中只有一个物理接口,因此无需定义网桥。

在此示例中,VLAN 交换机端口的作用类似于 Linux 盒的接口。您可以轻松地将此概念扩展到其他应用和场景。使用 24 端口 VLAN 交换机,如果您创建 23 个独立的 VLAN,则可以在 Linux 盒中拥有相当于 23 个以太网接口。第 24 个端口将用于将 Linux 盒连接到交换机,并且需要标记所有 23 个 VLAN 的数据包。

测试

您可以使用 tcpdump 来查看线路上的标记和未标记数据包,并确保流量出现在预期的接口上。使用 -e 选项查看以太网标头信息(显示 802.1Q 标记),使用 -i 选项在特定接口上进行嗅探。例如,运行以下命令以显示 VLAN 10 的流量

tcpdump -e -i eth0.10

您应该看到没有 VLAN 标记的正常流量。如果 VLAN 10 包含多个主机,您至少应该开始看到 ARP 和其他正常广播数据包(像任何交换网络一样,您不会看到未寻址到您的主机/网桥的单播数据包)。

如果 eth0.10 VLAN 接口在上面工作正常,如果您查看底层物理接口 eth0 上的流量,您应该会看到标记的 802.1Q 数据包

tcpdump -e -i eth0

如果您在与 eth0.10 捕获同时运行此命令,您应该会看到相同数据包的标记版本(以及在 eth0 上设置的任何其他 VLAN 接口的数据包)。

资源

Linux 的 802.1Q VLAN 实现 (vlan 包): www.candelatech.com/~greear/vlan.html

bridge-utils: www.linuxfoundation.org/collaborate/workgroups/networking/bridge

ebtables: ebtables.sourceforge.net

IEEE 802.1Q-2005—虚拟桥接局域网: standards.ieee.org/getieee802/download/802.1Q-2005.pdf

IEEE 802.1D-2004—媒体访问控制 (MAC) 桥接器: standards.ieee.org/getieee802/download/802.1D-2004.pdf

Henry Van Styn 是 IntelliTree Solutions 的创始人,IntelliTree Solutions 是一家位于俄亥俄州辛辛那提的 IT 咨询和软件开发公司。Henry 已经开发软件和解决方案超过十年,范围从复杂的 Web 应用程序到低级网络和系统实用程序。他是 Strong Branch Linux 的作者,Strong Branch Linux 是一个基于 Gentoo 的内部服务器发行版。可以通过 www.intellitree.com 联系 Henry。

加载 Disqus 评论