探索 二层网络 (Layer 2) 的两个核心实验:
- Linux Bridge: 模拟交换机,理解 MAC 地址表和 ARP。
- VLAN 单臂路由: 模拟企业级网络,通过一根线实现不同业务部门的隔离与互通。
Linux 网络实验室 (二):玩转二层交换 ------ Linux Bridge 与 VLAN 单臂路由
我们通过 Linux Namespace 模拟了路由器和 NAT,搞懂了三层网络(Layer 3)是如何工作的。
今天,我们将目光下移,深入 二层网络 (Data Link Layer) 。我们将把 Linux 变成一台交换机,并亲手搭建一个企业级网络中非常经典的架构:基于 VLAN 的单臂路由 (Router-on-a-Stick)。
实验三:手搓交换机 (Linux Bridge)
路由器通过 IP 地址转发数据,而交换机(Switch)通过 MAC 地址转发数据。在 Linux 中,我们用 Bridge (网桥) 来模拟交换机。
1. 实验拓扑
这次我们不需要配置 Gateway,因为两台 PC 在同一个"房间"(网段)里。
text
Namespace: host1 Namespace: switch Namespace: host2
+----------------+ +--------------------+ +----------------+
| IP: 192.168.1.1| | Bridge: br0 | | IP: 192.168.1.2|
| | <------> | [port1] [port2] | <------> | |
+----------------+ +--------------------+ +----------------+
2. 实战命令
第一步:搭建物理连接
我们需要一个专门的房间 switch 来放置我们的虚拟交换机。
bash
# 创建 Namespace
sudo ip netns add host1
sudo ip netns add host2
sudo ip netns add switch
# 制作网线并连接
sudo ip link add veth1 type veth peer name veth1-br
sudo ip link set veth1 netns host1
sudo ip link set veth1-br netns switch
sudo ip link add veth2 type veth peer name veth2-br
sudo ip link set veth2 netns host2
sudo ip link set veth2-br netns switch
第二步:组装交换机 (Bridge)
这是核心步骤。我们将创建一个 bridge 设备,并把网线插上去。
bash
# 在 switch 房间里创建网桥 br0
sudo ip netns exec switch ip link add name br0 type bridge
sudo ip netns exec switch ip link set br0 up
# 把网线头"插"到网桥上 (set master)
sudo ip netns exec switch ip link set veth1-br master br0
sudo ip netns exec switch ip link set veth1-br up
sudo ip netns exec switch ip link set veth2-br master br0
sudo ip netns exec switch ip link set veth2-br up
第三步:配置 IP 并测试
bash
# 配置 Host1
sudo ip netns exec host1 ip addr add 192.168.1.1/24 dev veth1
sudo ip netns exec host1 ip link set veth1 up
sudo ip netns exec host1 ip link set lo up
# 配置 Host2
sudo ip netns exec host2 ip addr add 192.168.1.2/24 dev veth2
sudo ip netns exec host2 ip link set veth2 up
sudo ip netns exec host2 ip link set lo up
# Ping 测试
sudo ip netns exec host1 ping 192.168.1.2
Ping 通了!这说明 br0 成功地在二层将两根网线"短接"在了一起。
实验四:VLAN 单臂路由 (Router on a Stick)
在公司网络中,财务部和技术部虽然连在同一个交换机上,但必须隔离。我们使用 VLAN (虚拟局域网) 来打标签,并用 单臂路由 来实现受控互通。
1. 实验拓扑
- PC1: 属于 VLAN 10 (模拟财务部)
- PC2: 属于 VLAN 20 (模拟技术部)
- Router: 只有一根线连接交换机,但通过子接口同时处理两个 VLAN 的流量。
text
Namespace: PC1 (VLAN 10) Namespace: PC2 (VLAN 20)
+-----------------------+ +-----------------------+
| IP: 192.168.10.2 | | IP: 192.168.20.2 |
+----------+------------+ +-----------+-----------+
| Tag: 10 | Tag: 20
+---------+-----------------------------------+---------+
| Switch (br0) - 透明转发 |
+-------------------------+-----------------------------+
| Trunk Link (Tag 10, 20)
+---------+----------+
| (veth-r-lan) |
| | | |
| veth.10 veth.20| <-- 子接口
| 10.1 20.1 |
+--------------------+
Namespace: ROUTER
2. 核心配置步骤
第一步:物理层连接
(假设我们已经清理了环境,重新创建了 pc1, pc2, switch, router 四个 namespace,并用网桥 br0 将它们物理上连通。具体命令参考实验三,这里省略重复造线过程。)
第二步:配置 Router 的 VLAN 子接口 (关键)
Router 不需要两张物理网卡,我们在一张卡上"变"出两张逻辑网卡。
bash
# 启动物理接口
sudo ip netns exec router ip link set veth-r-lan up
# 创建 VLAN 10 子接口
sudo ip netns exec router ip link add link veth-r-lan name veth-r-lan.10 type vlan id 10
sudo ip netns exec router ip addr add 192.168.10.1/24 dev veth-r-lan.10
sudo ip netns exec router ip link set veth-r-lan.10 up
# 创建 VLAN 20 子接口
sudo ip netns exec router ip link add link veth-r-lan name veth-r-lan.20 type vlan id 20
sudo ip netns exec router ip addr add 192.168.20.1/24 dev veth-r-lan.20
sudo ip netns exec router ip link set veth-r-lan.20 up
# 开启转发
sudo ip netns exec router sysctl -w net.ipv4.ip_forward=1
第三步:配置 PC (模拟 VLAN 终端)
为了模拟效果,我们让 PC 自己发出带 Tag 的包(现实中通常由交换机打 Tag)。
bash
# PC1 (VLAN 10)
sudo ip netns exec pc1 ip link add link veth-pc1 name veth-pc1.10 type vlan id 10
sudo ip netns exec pc1 ip addr add 192.168.10.2/24 dev veth-pc1.10
sudo ip netns exec pc1 ip link set veth-pc1.10 up
# 网关指向 Router 的 VLAN 10 接口
sudo ip netns exec pc1 ip route add default via 192.168.10.1
# PC2 (VLAN 20)
# (配置同上,只需将 ID 改为 20,IP 改为 192.168.20.2,网关改为 192.168.20.1)
第四步:见证奇迹
bash
# PC1 Ping PC2
sudo ip netns exec pc1 ping 192.168.20.2
通了!数据包带着 Tag 10 进路由,被剥离,查路由表,贴上 Tag 20,再发给 PC2。
💡 深度思考与排错分析
1. ARP 表 vs FDB 表:谁是谁的通讯录?
在实验中,如果想强制让交换机重新学习 MAC 地址,我们应该清空哪里?这里经常混淆两张表:
- Host 上的 ARP 表 (
ip neigh): 记录 IP -> MAC 的映射。- 独白: "我要给 192.168.1.2 发信,但我不知道它的 MAC 地址,我得发个广播问问。"
- Switch 上的 FDB 表 (
bridge fdb): 记录 MAC -> Port (接口) 的映射。- 独白: "刚才 MAC 地址为 AA:BB... 的人在 1 号口说话了,我记下来。下次有给它的信,我直接送 1 号口。"
排错技巧:
如果你想观察交换机"学习"的过程,最佳做法是 清空发送端 Host 的 ARP 表 (ip neigh flush all)。
原因: 只有 Host 忘了对方的 MAC,它才会发送 ARP Broadcast (广播)。只有当 Switch 听到这个广播,或者看到回复包时,Switch 的 FDB 表才能学到 MAC 地址的位置。
2. 为什么 Router 看不到局域网内的流量?
在实验三(同网段互通)中,如果你在 Router 上抓包,你会发现:
- 可以看到 PC 发出的 ARP 广播请求。
- 但是,完全看不到 PC1 Ping PC2 的 ICMP 数据包。
深度解析:
这就是 交换机 (Switch) 和 集线器 (Hub) 的本质区别------隔离冲突域 。
当 Switch 的 FDB 表学习完成后,它知道 PC1 在接口 A,PC2 在接口 B。
当 PC1 给 PC2 发数据时(单播 Unicast),Switch 会精确地把数据从接口 A 搬运到接口 B。连接在接口 C 的 Router 完全被当作了"路人甲",数据包根本不会流向它。
这解释了为什么在公司局域网里,你无法轻易抓到同事的聊天数据包(除非配置了端口镜像)。