二层网络

前段时间学习了二、三层网络基础。想用自己的话来总结下目前理解到东西,方便自己复习,如有不对请大家指出, 本篇是二层网络的总结。

1. 实验环境搭建

1.1 网络拓扑设计

管理网络配置(用于SSH远程访问):

  • EIP: 192.168.18.172
  • 管理网: VPC 172.16.0.0/16
  • switch, vm1, vm2, vm3 的 eth0 网卡都连接到管理网
    • vm1: 172.16.0.2
    • vm2: 172.16.0.3
    • vm3: 172.16.0.4
    • switch: 172.16.0.5

二层网络配置

  • 创建网络 n1, n2, n3
  • switch 连接 n1, n2, n3 的 eth1, eth2, eth3
  • 虚拟机二层网络配置:
    • vm1: n1, eth1, 10.0.0.11, MAC: 52:54:65:f1:c5:45
    • vm2: n2, eth1, 10.0.0.12, MAC: 52:54:65:12:a7:d0
    • vm3: n3, eth1, 10.0.0.13, MAC: 52:54:65:46:10:a1

1.2 虚拟机配置

上述配置只是为了可以用SSH远程访问这些虚拟机,便于后续实验操作。

2. 二层网络基础概念

2.1 二层转发原理

二层网络的核心原理是:收到报文的目标MAC地址不是自己的MAC地址时,转发给同网络的其他端口

同一个网段通过二层进行通信,也就是使用MAC地址互相访问。但是每个VM并不知道其他VM的MAC地址,应用程序还是用IP进行通信。所以建立网络连接的第一步是解析MAC地址。

2.2 MAC地址学习机制

交换机通过泛洪学习(Flood & Learn)机制来维护MAC地址表:

  1. 学习阶段:在端口收到报文时,记录源MAC地址和当前时间到FDB表
  2. 转发阶段:如果报文的目标MAC能在FDB表中查到,则转发给对应端口
  3. 泛洪阶段:如果报文的目标MAC是广播地址、未知单播或组播(BUM),发到所有端口
  4. 老化阶段:FDB表记录的时间超过老化时间后(通常是5分钟),自动删除记录

3. 实验验证

3.1 交换机配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 安装网桥工具
apt install -y bridge-utils

# 创建 br0 网桥(类似虚拟机交换机),并将 eth1~eth3连接到br0上
brctl addbr br0
brctl addif br0 eth1
brctl addif br0 eth2
brctl addif br0 eth3
brctl show

# 启用所有网络接口
ip link set eth1 up
ip link set eth2 up
ip link set eth3 up
ip link set br0 up

3.2 虚拟机网络配置

1
2
3
4
5
6
7
# 为虚拟机配置临时IP地址
# vm1
ifconfig eth1 10.0.0.11
# vm2
ifconfig eth1 10.0.0.12
# vm3
ifconfig eth1 10.0.0.13

3.3 ARP协议分析

实验:vm1 ping vm3

1
2
3
4
5
6
7
8
# vm1 -> vm3 通信测试
root@vm1:~# ping 10.0.0.13 -c 1
PING 10.0.0.13 (10.0.0.13) 56(84) bytes of data.
64 bytes from 10.0.0.13: icmp_seq=1 ttl=64 time=0.596 ms

--- 10.0.0.13 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.596/0.596/0.596/0.000 ms

抓包分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# vm2 抓包(观察者视角)
root@vm2:~# tcpdump -i eth1 -nel
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
05:29:50.865544 52:54:65:65:65:6a > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 10.0.0.13 tell 10.0.0.11, length 28

# vm3 抓包(目标主机视角)
root@vm3:~# tcpdump -i eth1 -nel
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
# vm1 发 ARP 请求找 vm3 第一次通信,未知 MAC 地址
05:29:50.862687 52:54:65:65:65:6a > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 10.0.0.13 tell 10.0.0.11, length 28
# vm3 回应 ARP,但不会缓存 vm1 的 MAC ARP 响应包是单播,仅 vm1 收到
05:29:50.862704 52:54:65:96:16:0c > 52:54:65:65:65:6a, ethertype ARP (0x0806), length 42: Reply 10.0.0.13 is-at 52:54:65:96:16:0c, length 28
# vm1 发 ICMP 请求找 vm3
05:29:50.862982 52:54:65:65:65:6a > 52:54:65:96:16:0c, ethertype IPv4 (0x0800), length 98: 10.0.0.11 > 10.0.0.13: ICMP echo request, id 2949, seq 1, length 64
# vm3 回 ICMP 给 vm1
05:29:50.862992 52:54:65:96:16:0c > 52:54:65:65:65:6a, ethertype IPv4 (0x0800), length 98: 10.0.0.13 > 10.0.0.11: ICMP echo reply, id 2949, seq 1, length 64
# 隔了 5 秒左右 vm3 发 ARP 请求找 vm1
05:29:55.903301 52:54:65:96:16:0c > 52:54:65:65:65:6a, ethertype ARP (0x0806), length 42: Request who-has 10.0.0.11 tell 10.0.0.13, length 28
# vm1 回应 ARP,但不会缓存 vm3 的 MAC ARP 响应包是单播,仅 vm3 收到
05:29:55.903649 52:54:65:65:65:6a > 52:54:65:96:16:0c, ethertype ARP (0x0806), length 42: Reply 10.0.0.11 is-at 52:54:65:65:65:6a, length 28

重要发现:为什么 vm3 会隔了 5 秒左右才发 ARP 请求找 vm1?

虽然 vm1 发了 ARP 请求,vm3 回答了没错,但ARP 回复不是广播包,是单播给 vm1 的。vm3 回应的时候并不会自动缓存对方(vm1)的 IP-MAC 绑定,这是常见误解。

3.4 交换机FDB表分析

查看交换机的MAC地址表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 到switch上查看交换机的fdb表,也就是mac地址表
root@switch:~# bridge fdb show br br0
52:54:65:df:02:d1 dev eth1 vlan 1 master br0 permanent
52:54:65:df:02:d1 dev eth1 master br0 permanent
33:33:00:00:00:01 dev eth1 self permanent # ipv6 multicast mac地址
01:00:5e:00:00:01 dev eth1 self permanent # ipv4 multicast mac地址
33:33:ff:df:02:d1 dev eth1 self permanent # ipv6 用于NDP邻居发现
52:54:65:bf:76:62 dev eth2 vlan 1 master br0 permanent
52:54:65:bf:76:62 dev eth2 master br0 permanent
33:33:00:00:00:01 dev eth2 self permanent
01:00:5e:00:00:01 dev eth2 self permanent
33:33:ff:bf:76:62 dev eth2 self permanent
52:54:65:37:10:42 dev eth3 master br0 permanent
52:54:65:37:10:42 dev eth3 vlan 1 master br0 permanent
52:54:65:46:10:a1 dev eth3 master br0
33:33:00:00:00:01 dev eth3 self permanent
01:00:5e:00:00:01 dev eth3 self permanent
33:33:ff:37:10:42 dev eth3 self permanent
33:33:00:00:00:01 dev br0 self permanent
01:00:5e:00:00:01 dev br0 self permanent
33:33:ff:37:10:42 dev br0 self permanent

其中包含 permanent 的表示bridge和端口的物理地址,不需要关注。

查看动态学习的MAC地址

1
2
3
root@route1:~# bridge -statistics fdb show br br0|grep -v perm
52:54:65:65:65:6a dev eth1 used 9/9 master br0
52:54:65:96:16:0c dev eth3 used 9/9 master br0

以第一行为例,它表示目标是 52:54:65:65:65:6a 的报文发到 eth1 端口,也就是MAC和端口的映射关系。

4. 深入理解

4.1 未知单播泛洪实验

实验:vm2 向不存在的MAC地址发送ICMP报文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# vm2 往 52:54:a7:bb:72:00 发一个icmp报文
# 配置静态arp表,让ping命令不通过arp广播返回解析mac,只发icmp报文,这样vm2的mac地址不会被学习到
root@vm2:~# ip neigh add 10.0.0.10 lladdr 52:54:a7:bb:72:00 dev eth1
root@vm2:~# ping 10.0.0.10 -c 1 -w 1
PING 10.0.0.10 (10.0.0.10) 56(84) bytes of data.

--- 10.0.0.10 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

# switch学习到了vm2的mac,但是没有52:54:a7:bb:72:00的mac
root@route1:~# bridge -statistics fdb show br br0 | grep -v perm
32:ee:65:c1:fb:26 dev eth1 used 309/309 master br0 stale
52:54:65:ba:72:bf dev eth2 used 54/8 master br0

# vm1和vm3都收到了这个报文,没有回复报文
root@vm1:~# tcpdump -i eth1 -nel
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
13:03:04.224521 52:54:65:ba:72:bf > 52:54:a7:bb:72:00, ethertype IPv4 (0x0800), length 98: 10.0.0.12 > 10.0.0.10: ICMP echo request, id 6113, seq 1, length 64

root@vm3:~# tcpdump -i eth1 -nel
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
13:03:04.214844 52:54:65:ba:72:bf > 52:54:a7:bb:72:00, ethertype IPv4 (0x0800), length 98: 10.0.0.12 > 10.0.0.10: ICMP echo request, id 6113, seq 1, length 64

分析过程

  1. vm2 发出的报文

    • 由于静态 ARP 已设置,vm2 直接构造了目标 MAC 是 52:54:a7:bb:72:00 的 ICMP 报文,无需 ARP 广播。
  2. 交换机没有目标 MAC 的 FDB 记录

    • 52:54:a7:bb:72:00 是未知单播,交换机会将其按 BUM(Broadcast, Unknown Unicast, Multicast)方式泛洪到所有端口(除了来源端口)。
    • 所以 vm1、vm3 都收到这个包。
  3. 为什么没有回应?

    • 可能 1:vm1、vm3 不是 10.0.0.10
      • 它们收到包,但并不是目标主机,因此不会回应。
      • 抓包看到报文到了,但不会处理。
    • 可能 2:目标主机(MAC 为 52:54:a7:bb:72:00)根本不在网内
      • 也许这个 MAC 没有挂载在任何 VM 上,或者主机未启用接口 / 未监听。

4.2 交换机vs集线器

之前在大学宿舍中使用叫集线器(Hub)的设备,形态跟交换机有点类似,它们的差异在于:

  • 集线器:没有学习能力,对所有报文都泛洪
  • 交换机:具有MAC地址学习能力,可以精确转发

所以集线器只能用于流量低的办公和家用领域,不适合IDC环境。

5. 总结

通过本次实验,我们深入理解了:

  1. 二层网络的基本原理:基于MAC地址的转发机制
  2. ARP协议的工作过程:IP到MAC地址的解析过程
  3. 交换机的学习机制:通过泛洪学习建立MAC地址表
  4. BUM流量的处理:广播、未知单播、组播的泛洪转发
  5. 交换机与集线器的区别:学习能力是核心差异

这些知识为理解更复杂的网络架构奠定了基础。