在云计算时代,虚拟机和容器已经成为标配。它们背后的网络管理都离不开一样东西,就是虚拟网络设备,或者叫虚拟网卡,tap/tun 就是在云计算时代非常重要的虚拟网络网卡。
tap/tun 是 Linux 内核 2.4.x 版本之后实现的虚拟网络设备,不同于物理网卡靠硬件网路板卡实现,tap/tun 虚拟网卡完全由软件来实现,功能和硬件实现完全没有差别,它们都属于网络设备,都可以配置 IP,都归 Linux 网络设备管理模块统一管理。
作为网络设备,tap/tun 也需要配套相应的驱动程序才能工作。tap/tun 驱动程序包括两个部分,一个是字符设备驱动,一个是网卡驱动。这两部分驱动程序分工不太一样,字符驱动负责数据包在内核空间和用户空间的传送,网卡驱动负责数据包在 TCP/IP 网络协议栈上的传输和处理。
在 Linux 中,用户空间和内核空间的数据传输有多种方式,字符设备就是其中的一种。tap/tun 通过驱动程序和一个与之关联的字符设备,来实现用户空间和内核空间的通信接口。
在 Linux 内核 2.6.x 之后的版本中,tap/tun 对应的字符设备文件分别为:
设备文件即充当了用户空间和内核空间通信的接口。当应用程序打开设备文件时,驱动程序就会创建并注册相应的虚拟设备接口,一般以 tunX
或 tapX
命名。当应用程序关闭文件时,驱动也会自动删除 tunX
和 tapX
设备,还会删除已经建立起来的路由等信息。
tap/tun 设备文件就像一个管道,一端连接着用户空间,一端连接着内核空间。当用户程序向文件 /dev/net/tun
或 /dev/tap0
写数据时,内核就可以从对应的 tunX
或 tapX
接口读到数据,反之,内核可以通过相反的方式向用户程序发送数据。
tap/tun 通过实现相应的网卡驱动程序来和网络协议栈通信。一般的流程和物理网卡和协议栈的交互流程是一样的,不同的是物理网卡一端是连接物理网络,而 tap/tun 虚拟网卡一般连接到用户空间。
如下图的示意图,我们有两个应用程序 A、B,物理网卡 eth0
和虚拟网卡 tun0
分别配置 IP:10.1.1.11
和 192.168.1.11
,程序 A 希望构造数据包发往 192.168.1.0/24
网段的主机 192.168.1.1
。
基于上图,我们看看数据包的流程:
192.168.1.1
,通过 socket A
将这个数据包发给协议栈。tun0
出去。tun0
发现自己的另一端被应用程序 B 打开了,于是将数据发给程序 B.eth0
的 IP,目的 IP 是 10.1.1.0/24
的网关 10.1.1.1
,封装原来的数据的数据包,重新发给协议栈。eth0
发出。后续步骤,当 10.1.1.1
收到数据包后,会进行解封装,读取里面的原始数据包,继而转发给本地的主机 192.168.1.1
。当接收回包时,也遵循同样的流程。
在这个流程中,应用程序 B 的作用其实是利用 tun0
对数据包做了一层隧道封装。其实 tun
设备的最大用途就是用于隧道通信的。
看到这里,你可能还不大明白 tap/tun 的区别。 tap 和 tun 虽然都是虚拟网络设备,但它们的工作层次还不太一样。
从上面的数据流程中可以看到,tun
设备充当了一层隧道,所以,tap/tun 最常见的应用也就是用于隧道通信,比如 V**,包括 tunnel 和应用层的 IPsec 等,其中比较有名的两个开源项目是 openV** 和 VTun。
tun/tap 虚拟网卡,对应于物理网卡,如 eth0。
tun/tap 驱动包括字符设备驱动和网卡驱动。
tun/tap 常用于隧道通信。