本文首次编辑于2022年春季。因为有需要,所以翻出来,顺便发布
写在前面
- Linux虚拟网卡测试程序:tunread.c
Linux虚拟网卡概述
Linux虚拟网卡,是在Linux内核2.4.x版本之后完全由软件实现的虚拟网络设备,在功能上和物理网卡没有区别,由Linux网络设备管理模块统一来管理。
与物理网卡不同的是,在没有进行其他配置(如网桥)的情况下,Linux虚拟网卡并不连接到任何真实的物理链路,在Linux虚拟网卡中传输的所有报文均在本机中传输。
虚拟网卡数据包的流向
那么,在通过Socket协议栈向网卡发送数据时,数据包的走向如何呢?下图可以较好的对数据流进行描述。
从图中我们可以直观地看到:用户程序通过Socket接口操作物理网卡和虚拟网卡的方法没有任何不同,区别在于物理网卡和虚拟网卡对于收发数据包的处理方式。物理网卡将Socket用户的数据包发到物理链路上,并从物理链路上接收数据包返回给Socket用户;而虚拟网卡将Socket用户的数据包发到本地的一个字符设备中,并从该字符设备中读取的数据返回给Socket用户。换句话说,虚拟网卡把Socket用户的网络数据包“重定向”到了一个字符设备中!这使得操作这个字符设备的其他程序可以通过文件接口接收Socket用户发来的包,或向Socket用户发包。
三层虚拟网卡(TUN)与二层虚拟网卡(TAP)
从虚拟网卡对应的字符设备中读取到的网络数据包是何种格式?这就涉及到了TUN和TAP虚拟网卡的区别。TUN网卡只模拟到第三层,只有IP地址而没有MAC地址;TAP网卡能模拟到第二层,既有IP地址也有MAC地址。利用字符设备接口操作TUN和TAP网卡,前者需要处理三层包(例如IP数据报),而后者需要处理二层包(以太网帧)。
虚拟网卡的典型应用场景
虚拟网卡比较典型的应用场景就是是虚拟机。虚拟机程序(如QEMU、VirtualBox等)将宿主机上的虚拟网卡字符设备作为“物理链路”提供给虚拟机,宿主机与虚拟机之间就可以通过虚拟网卡建立网络连接了。
虚拟网卡还有一类比较典型的应用场景,那就是虚拟专用网络,英语名称为Virtual Private Network,简称VPN。VPN在教育、科研、工业、█████等领域具有广泛的应用。一个典型的例子:当校内学生/企业员工需要异地访问学校/企业内网资源时,VPN就是必不可少的工具。VPN的客户端程序在用户处创建一个虚拟网卡,分配内网IP地址,再通过建立在互联网上的虚拟链路连接到学校/公司的VPN服务端程序,进而访问内网资源。
虚拟网卡测试
作为验证,笔者创建了一个虚拟网卡tun0
,并设置其IP地址为10.10.10.1/8
,然后利用nc
工具向该网卡发送目标为10.10.10.10:10240
的UDP数据报。同时,笔者利用一个C程序读取tun0
虚拟网卡对应的字符设备接口,并逐字节观察读出的数据报,发现可以收到正常的UDP/IP数据报文。具体过程如下:
- 利用
tunctl
命令创建一个虚拟网卡tun0
:tunctl -u root -3 -t tun0
,其中:
-
-u root
表示该网卡由root用户专用. -
-3
表示建立三层虚拟网卡,即TUN类型的网卡。 -
-t tun0
指定了网卡的名字为tun0。
-
利用
ifconfig
命令设置tun0
网卡的IP地址,并启用这个网卡:ifconfig tun0 10.10.10.1 netmask 255.0.0.0 up
- 在
tapread.c
文件中,利用Linux字符设备接口监听tun0
网卡收到的信息。 -
用
nc
命令向tun
网卡发送UDP报文。nc
命令参数解释如下:nc -4nu 10.10.10.10 10240
,其中:
-
-4nu
表示使用IPv4、不使用域名解析、使用UDP。 -
10.10.10.10
表示目的IP。 -
10240
表示目的端口。
- 查看第3步中监听到的网络流量。
- 红色部分是IPv4报头:头部长度20,报文总长41。
-
橙色部分是IPv4报头的源地址:
10.10.10.1
-
黄色部分是IPv4报头的目的地址:
10.10.10.10
-
绿色部分是UDP报头:源端口45004(由
nc
命令自动分配),目的端口10240 -
紫色部分是数据:
"Hello World!\n"
如果进一步配合iptables
,我们就能让虚拟网卡充当虚拟机程序、VPN程序与物理网络沟通的桥梁。
文章评论