veth设备

veth 设备介绍

  • veth 和其它网络设备一样,一端连接的是内核协议栈;
  • veth 设备是成对存在的,另一端两个设备彼此连接;
  • 一个设备收到来自协议栈的请求数据后,会将数据发送到另一台设备上去。
+----------------------------------------------------------------+
|                                                                |
|       +------------------------------------------------+       |
|       |             Newwork Protocol Stack             |       |
|       +------------------------------------------------+       |
|              ↑               ↑               ↑                 |
|..............|...............|...............|.................|
|              ↓               ↓               ↓                 |
|        +----------+    +-----------+   +-----------+           |
|        |   eth0   |    |   veth0   |   |   veth1   |           |
|        +----------+    +-----------+   +-----------+           |
|192.168.1.11  ↑               ↑               ↑                 |
|              |               +---------------+                 |
|              |         192.168.2.11     192.168.2.1            |
+--------------|-------------------------------------------------+
               ↓
         Physical Network

物理网卡的 IP 地址为 192.168.1.11veth0veth1 的 IP 分别为 192.168.2.11192.168.2.1


只配置一个 veth 的 IP 地址

sudo ip link add veth0 type veth peer name veth1
sudo ip addr add 192.168.2.11/24 dev veth0
sudo ip link set veth0 up
sudo ip link set veth1 up

这里给 veth0 配置 IP 地址,但是不配置 veth1 的 IP 地址,尝试 ping 一下 veth1 发现 ping 不通,通过 tcpdump 设备监听 ARP 应答包:

dev@debian:~$ sudo tcpdump -n -i veth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
20:20:18.285230 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
20:20:19.282018 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
20:20:20.282038 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
20:20:21.300320 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
20:20:22.298783 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
20:20:23.298923 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28

dev@debian:~$ sudo tcpdump -n -i veth1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth1, link-type EN10MB (Ethernet), capture size 262144 bytes
20:20:48.570459 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
20:20:49.570012 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
20:20:50.570023 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
20:20:51.570023 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
20:20:52.569988 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
20:20:53.570833 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28

可以发现 ARP 包并没有回应,ARP 协议是广播查询对应 IP 值的 MAC 地址,具体流程如下:

  • ping 进程构造 ICMP echo 请求包,并通过 socket 发送给协议栈;
  • 协议栈根据目的 IP 地址和系统路由表查询 192.168.2.1 的数据包应该由 192.168.2.11 IP 地址发送出去;
  • 由于是第一次访问 192.168.2.1,且目的IP 和本地IP是在同一个网段,所以协议栈会先发送 ARP数据包出去,询问 192.168.2.1 的 MAC 地址;
  • 协议栈将 ARP 包交给 veth0,并由它发送出去;由于 veth0 的另一端连接的是 veth1,所以 ARP数据包转发给了 veth1;
  • veth1 收到 ARP 数据包后转发给另一端的协议栈;
  • 协议栈的本地设备列表中由于没有 192.168.2.1 这个IP值,所以会丢弃该 ARP 数据包,这就是只能看到 ARP 请求包,但是无法查看应答包的原因。

配置两个 veth 设备的 IP 地址

给 veth1 设备配置 IP 地址:
sudo ip addr add 192.168.2.1/24 dev veth1
接着尝试 ping 192.168.2.1 这个 IP地址,输出如下:

dev@debian:~$ ping -c 4 192.168.2.1 -I veth0
PING 192.168.2.1 (192.168.2.1) from 192.168.2.11 veth0: 56(84) bytes of data.
64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=0.032 ms
64 bytes from 192.168.2.1: icmp_seq=2 ttl=64 time=0.048 ms
64 bytes from 192.168.2.1: icmp_seq=3 ttl=64 time=0.055 ms
64 bytes from 192.168.2.1: icmp_seq=4 ttl=64 time=0.050 ms

--- 192.168.2.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 0.032/0.046/0.055/0.009 ms

发现成功建立连接,尝试抓包结果如下:

dev@debian:~$ sudo tcpdump -n -i veth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
20:23:43.113062 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24169, seq 1, length 64
20:23:44.112078 IP 192.168.2.11 
> 192.168.2.1: ICMP echo request, id 24169, seq 2, length 64
20:23:45.111091 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24169, seq 3, length 64
20:23:46.110082 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24169, seq 4, length 64


dev@debian:~$ sudo tcpdump -n -i veth1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth1, link-type EN10MB (Ethernet), capture size 262144 bytes
20:24:12.221372 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24174, seq 1, length 64
20:24:13.222089 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24174, seq 2, length 64
20:24:14.224836 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24174, seq 3, length 64
20:24:15.223826 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24174, seq 4, length 64

数据包的发送流程如下:

  • ping 进程构造的 ICMP echo 请求包,并通过 socket 发送给协议栈;
  • 由于 ping 命令指定了数据包走 veth0 ,而且本地 ARP缓存中有相关的记录,所以不再发送 ARP数据包,而是直接将数据包交给 veth0;
  • 由于 veth0 的一端连接着 veth1,另一端连接着网络协议栈,所以 ICMP echo 请求包转发给了 veth1
  • veth1 接收到请求数据包后转发给另一端的网络协议栈;
  • 网络协议栈查看自己的设备列表,发现有 192.168.2.1 这个IP,于是构造 ICMP echo 应答包,并准备返回;
  • 网络协议栈查看自己的路由表,发现发往 192.168.2.1 的数据包应该走 lo口,于是将应答包发送给 lo设备;
  • lo设备在收到来自协议栈的应答包后,转手将数据返还给了协议栈(相当于协议栈通过发送流程把数据包发送给 lo设备,lo设备再将数据包交给协议栈);
  • 协议栈接收到应答包后,发现有 socket 需要该数据包,于是交给相应的 socket;

总结

上面的介绍可以看出,从 veth0 发送出去的数据包,会转发到 veth1 上,如果目的地址是 veth1 的IP地址,就能够被网络协议栈处理,否则连 ARP数据包都无法返回。所以 veth 设备如果不借助其它虚拟设备,数据包只能在本地协议栈中循环,无法发送到外部网络。

posted @ 2024-02-17 23:40  Stitches  阅读(11)  评论(0编辑  收藏  举报