Linux 网络实验(2)

探索 二层网络 (Layer 2) 的两个核心实验:

  1. Linux Bridge: 模拟交换机,理解 MAC 地址表和 ARP。
  2. 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 完全被当作了"路人甲",数据包根本不会流向它。

这解释了为什么在公司局域网里,你无法轻易抓到同事的聊天数据包(除非配置了端口镜像)。


相关推荐
哈基咪怎么可能是AI5 小时前
为什么我就想要「线性历史 + Signed Commits」GitHub 却把我当猴耍 🤬🎙️
linux·github
BingoGo8 小时前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack8 小时前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
十日十行1 天前
Linux和window共享文件夹
linux
木心月转码ing1 天前
WSL+Cpp开发环境配置
linux
JaguarJack1 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo1 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
崔小汤呀2 天前
最全的docker安装笔记,包含CentOS和Ubuntu
linux·后端
何中应2 天前
vi编辑器使用
linux·后端·操作系统
何中应2 天前
Linux进程无法被kill
linux·后端·操作系统