Linux tun 设备介绍
tun
是一种虚拟的3层虚拟网络设备,同时它也是一个字符设备,字符设备意味着可以把它当做一个文件,可以使用文件API
操作这个设备,例如 open/read/write
,由于它同时也是一个网络设备,所以它也可以像一个网卡一样,从内核网络协议栈中收发报文。所以从它架构上来看,tun
设备的一端连接着应用程序,一端连接着网络协议栈,如下图所示:
从在系统中的表象来看,字符设备的文件类型是c
,没有大小,但是有主次版本号:
1 | $ ls -alh /dev/net/tun |
tun
设备的创建是通过打开/dev/net/tun
这个文件,然后使用ioctl
系统调用对其进行clone
。也可以使用 ip
命令来实现tun
设备的创建:
ip tuntap add dev tun1 mod tun
新创建的 tun1
设备位于 /sys/class/net/
目录中:
1 | $ ll /sys/class/net/tun1 |
删除使用如下命令:
ip tuntap del dev tun1 mod tun
ICMP
示例
如前文所述,tun
设备的使用需要打开/dev/net/tun
并对其clone
之后才能进行使用,所以通用的创建tun
设备有如下的步骤:
1 | int tun_alloc(char *dev, int flags) |
创建tun
设备需要是root
的用户,或者该应用程序需要具有CAP_NET_ADMIN
权限,/dev/net/tun
必须以读写方式打开,它是创建任何tun/tap
虚拟接口的起点,因此也被称为克隆设备(clone device
)。操作(open()
)后会返回一个文件描述符,但此时还无法与接口通信。下一步会使用一个特殊的ioctl()
系统调用,该函数的入参为上一步得到的文件描述符,以及一个TUNSETIFF
常数和一个指向描述虚拟接口的结构体指针。
tun_alloc
函数的两个参数中:
dev
:指的是创建的tun
设备的名称,如果*dev
为'\0'
,则内核会尝试使用第一个对应类型的可用的接口,例如从tun0
开始,如果tun0
存在就为tun1
;flags
:用于指定虚拟设备的类型,通常为IFF_TUN
或者IFF_TAP
,分别代表tun
或者tap
设备。除此之外,还有一个IFF_NO_PI
标志,可以与IFF_TUN
或IFF_TAP
配合使用。IFF_NO_PI
会告诉内核不需要提供报文信息,即告诉内核仅需要提供"纯"IP
报文,不需要其他字节。否则(不设置IFF_NO_PI
),会在报文开始处添加4
个额外的字节(2
字节的标识和2
字节的协议);
如果要完整的处理到达tun
设备的ICMP
请求,需要手动回响应:
1 | int main() |
完整的示例程序如下所示:
点击展开
1 |
|
将完整的源代码保存成文件tun.c
,使用如下的命令进行编译:
gcc -o taptun tun.c
打开终端运行编译生成的可执行程序taptun
可执行程序。然后打开另外一个终端,查询创建的tun0
设备:
1 | $ ifconfig tun0 |
这个时候的tun0
还未设置IP
地址,可以使用如下的命令进行设置并启用:
ip a a 10.1.1.2/24 dev tun0
ip l s tun0 up
再次查看该设备,可以看到IP
地址已经设置,并且处于启用状态:
1 | $ ifconfig tun0 |
创建设置并且设置IP
以后,可以看到操作系统会自动添加一条路由,表示发往 10.1.1.0/24
这个网段的所有报文都会经 tun0
设备发出:
1 | $ route -n |
所以只要ping
这个网段内的任一IP
都会到达tun0
设备,并且被我们的taptun
应用程序收到并处理,例如:
1 | $ ping -c 1 10.1.1.10 |
应用程序将会有如下的输出:
1 | $ ./taptun |
参考链接
- IP packets
- IPv4 - Packet Structure
- ICMP Explained and Packet Format
- https://juejin.cn/post/7057833934947614750
- https://blog.51cto.com/u_11299290/5107265
- https://ctimbai.github.io/2019/03/01/tech/net/vnet/基于taptun写一个ICMP程序/
- https://www.zhengwenfeng.com/pages/143447/#应用程序通过tun设备获取ping数据包
- https://lxd.me/a-simple-vpn-tunnel-with-tun-device-demo-and-some-basic-concepts
- https://www.rectcircle.cn/posts/linux-net-virual-05-tunnel/#tun-tap-虚拟设备
- https://www.zhaohuabing.com/post/2020-02-24-linux-taptun/
- https://www.luozhiyun.com/archives/684
- https://blog.avdancedu.com/52f625ca/
- https://www.xzcoder.com/posts/network/05-simple-vpn.html#程序测试