【NetDevOps】新一代网工需要了解的那点事儿(四)---tun/tap
4 tun/tap
虚拟网络设备也归内核的网络设备管理子系统管理。对于Linux内核网络设备管理模块来说,虚拟设备和物理设备没有区别,都是网络设备,都能配置IP,从网络设备来的数据,都会转发给协议栈,协议栈过来的数据,也会交由这些网络设备发送出去,至于是如何发送、发送到哪,这都由设备驱动来完成,跟Linux内核就没关系了。
4.1 tun/tap概述
从Linux文件系统来看,它们是用户可以用文件来操作的字符设备;但是从网络虚拟化的角度来看,它们是虚拟网卡,一端是APP一端是网络协议栈。与普通的网络接受发数据不同,tun/tap设备比较特殊,它是通过文件来收发数据包。如下图所示,tunX 和上面的 eth0 在逻辑上面是等价的, tunX 也代表了一个网络接口,虽然这个接口是系统通过软件所模拟出来的。网卡接口 tunX 所代表的虚拟网卡通过文件 /dev/tunX 与我们的应用程序(App) 相连,应用程序每次使用 write 之类的系统调用将数据写入该文件,这些数据会以网络层数据包的形式,通过该虚拟网卡,经由网络接口 tunX 传递给网络协议栈,同时该应用程序也可以通过 read 之类的系统调用,经由文件 /dev/tunX 读取到协议栈向 tunX 传递的所有数据包。其实这里的tunX和其他普通网卡基本一样,唯独的区别是这个虚拟网卡没有MAC地址,由于tunX仅能虚拟到网络层,所以要MAC地址也没用。但如果是tapX网卡则不同,因为它比runX更深入一层。对于协议栈来看tapX和物理网卡是没有区别的。
+-------------------------------------------------------------------------------+
| |
| +--------------+ +---------------+ |
| | APP | | Socket API | |
| | | | | |
| +------+-------+ +------+--------+ |
| | | |
| | | |
| USER +------+--------+ | |
+------------+ /dev/tunX +--------------------------------------------------+
|LINUX KERNEL| | | |
| +-------+-------+ +--------------+-----------+ |
| | | | |
| | | Network Protocal Stack | |
| | | | |
| | +--------------+-----------+ |
| | | |
| | | |
| | | |
| | | |
| | +--------------+ | |
| | | | | |
| +---------+ tunX +------------------+ |
| | | |
| +--------------+ By:[F0rGeEk] |
| |
++-------------------------------------------------------------------------------+
4.2 典型使用场景
较为常见的tun/tap使用场景有数据加密、数据压缩等,这里我们主要讲解最常用的VPN。它是利用tun设备做UDP的VPN,如下图所示。在用户层有两个APP1和APP2,Linux内核层有socket、网络协议站、网络设备。其中socket实质上是网络协议栈的一部分。这里我们将eth0的IP设定为10.8.8.11,eth0网络的网关为10.8.8.254;tun0的IP设定为12.1.1.11。我们这里假设VPN用户是eth0网络10.8.8.0/24中的某一台主机,这台主机本地有12.1.1.0/24网络,我们的目的是通过APP 1能与VPN主机本地网络中的成员进行通讯。
+--------------------------------------------------------------------------+
| +---------------------+ +-----------------------+ |
| | | | | |
| | AAP 1 | | APP 2 <-------+ |
| | | | | | |
| +---------+-----------+ +-----------+-----------+ | |
| | | | |
| | | | |
+--------------------------------------------------------------------------+
| | | | |
| | | | |
| v v | |
| +------+------+ +------+------+ | |
| | | | | | |
| | Socket 1 | | Socket 2 | | |
| | | | | | |
| +--+-------------+---------------------+-------------+-----+ | |
| | | | |
| | Network Protocal Stack | | |
| | | | |
| +---------+-----------------------------------+------------+ | |
| | | | |
| | | | |
| | | | |
| +-------v------+ +------v-------+ | |
| | | | | | |
| | eth0 | | tun0 | | |
| | | | | | |
| +-------+------+ +------+-------+ | |
| | 10.8.8.11/24 | 12.1.1.11/24 | |
| | +-------------------+ |
| | |
| | By:[F0rGeEk] |
+--------------------------------------------------------------------------+
v
Physical Network
这里假设10.8.8.33要与12.1.1.33通过VPN互访,下面我们来看看数据包的流程:
- 首选APP 1通过socket 1发送了一个目的地为12.1.1.33的数据包,socket将该数据包转发给网络协议栈;
- 协议栈收到该数据包后,根据本地路由规则进行匹配,将该数据包扔给tun0处理;
- tun0收到数据包后,由于另一端连着APP 2,所以它会直接将数据包转发至APP 2;
- APP 2收到数据包后,根据需要进行重构,重构时会将原有的数据包原封不动的包在新数据包中,然后再有APP 2发送出去。新数据包的源地址会变成eth0的地址10.8.8.11,而目的地址将会变成10.8.8.33;
- Socket收到由APP 2发出的数据包后,会直接转发给协议栈;
- 协议栈收到数据包后,匹配本地路由规则,将数据包转发给eth0;
- eth0收到数据包后,会直接通过物理网络将数据包发送出去;
- 当10.8.8.33收到数据包后,首先是打开数据包读取里面的原始数据,并将该数据包转发给12.1.1.33;如果12.1.1.33收到数据包并且回复的话,那么当收到12.1.1.33回复的数据包后进行数据包的重构,同样将原始数据封装在新的数据包中,再由原路返回;
- 这样最终APP 1即通过VPN完成了与12.1.1.33的通信。
4.3 tun与tap的区别
通过1.6.2小节的通信流程来看,tun/tap设备的用处是将协议栈中的部分数据包转发给用户空间的应用程序,再由用户空间的程序来处理这个数据包。tun/tap设备不仅能做基于DUP的VPN,类似的tunnel以及IPSec都是比较常用的场景。虽然它们的工作方式完全相同,但还是有一些区别:
- 户层程序通过tun设备只能读写IP数据包,而通过tap设备能读写链路层数据包;
- tun设备相当于是一个三层设备,,它无法与物理网卡做 bridge,但是可以通过三层交换(如 ip_forward)与物理网卡连通。可以使用ifconfig之类的命令给该设备设定 IP 地址;
- tap设备则相当于是一个二层设备,可以工作在数据链路层,拥有 MAC 层功能,可以与物理网卡做 bridge,支持 MAC 层广播。可以通过ifconfig之类的命令给该设备设定 IP 地址,甚至还可以给它设定 MAC 地址。