3.5.2 虚拟网络设备 TUN 和 TAP

TUN 和 TAP 是 Linux 内核自 2.4.x 版本引入的虚拟网卡设备,专为用户空间(user space)与内核空间(kernel space)之间的数据传输而设计。两者的主要区别如下:

  • TUN 设备:工作在网络层(Layer 3),用于处理 IP 数据包。它模拟一个网络层接口,使用户空间程序能够直接收发 IP 数据包;
  • TAP 设备:工作在数据链路层(Layer 2),用于处理以太网帧。与 TUN 设备不同,TAP 设备传输完整的以太网帧(包括数据链路层头部),使用户空间程序可以处理原始以太网帧。

Linux 系统中,内核空间和用户空间之间数据传输有多种方式,字符设备文件是其中一种。

TUN/TAP 设备对应的字符设备文件为 /dev/net/tun。当用户空间的程序打开(open)字符设备文件时,同时,TUN/TAP 的字符设备驱动会创建并注册相应的虚拟网卡,默认命名为 tunX 或 tapX。随后,用户空间程序读写(read/write)该文件描述符,就可以和内核网络栈进行数据交互了。

如图 3-13 所示,下面以 TUN 设备构建 VPN 隧道为例,说明其工作原理。

  1. 首先,一个普通的用户程序发起一个网络请求;
  2. 接着,数据包进入内核协议栈,并路由至 tun0 设备。路由规则如下:
    $ ip route show
    default via 172.12.0.1 dev tun0  // 默认流量经过 tun0 设备
    192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.3
    
  3. tun0 设备的字符设备文件 /dev/net/tun 由 VPN 程序打开。所以,用户程序发送的数据包不会直接进入网络,而是被 VPN 程序读取并处理。
  4. VPN 程序对数据包进行封装操作,封装(Encapsulation)是指在原始数据包外部包裹新的数据头部,就像将一个盒子放在另一个盒子中一样。
  5. 最后,处理后的数据包再次写入内核网络栈,并通过 eth0(即物理网卡)发送到目标网络。


图 3-13 VPN 中数据流动示意图

封装数据包以构建网络隧道,是实现虚拟网络的常见方式。例如,在本书第七章介绍的容器网络插件 Flannel 早期版本中,曾使用 TUN 设备来实现容器间的虚拟网络通信。但是,TUN 设备的数据传输需经过两次协议栈,并涉及多次封包与解包操作,导致了很大的性能损耗。这也是 Flannel 后来弃用 TUN 设备的主要原因。

总字数:679
Last Updated:
Contributors: isno