通过mptun源码彻底熟悉了基于tap/tun的vpn原理(用户态vpn)
VPN 客户端发送原理
- 配置对端VPN服务器的公网IP地址和端口
open "/dev/net/tun"创建一个tun网卡设备tun0,记录文件描述符fdifconfig tun0 12.0.0.1 netmask 255.255.255.255配置虚拟网卡ip route add 12.0.0.2 dev tun0配置目路由,设置目标ip为 12.0.0.2的数据走tun0口select (fd)利用select 监听tun0口,监听所有tun0口的网络数据read (fd)读取tun0达到的数据包, 然后加密整个数据包sendto(remote)然后把数据包当做数据负载发送到对端VPN服务器的公网ip地址
路由转发均根据本地路由表,回来的包还是由内核的 conntrack 表记录并转发
VPN 服务端原理
- 配置监听端口 60001, 然后创建一个tun0的虚拟网卡,
open "/dev/net/tun", 记录fd ifconfig tun0 12.0.0.2 netmask 255.255.255.255配置虚拟网卡ip route add 12.0.0.1 dev tun0配置目路由,设置目标ip为 12.0.0.1的数据走tun0口- 管理口内核TCP/IP驱动收到目标端口为60001的数据包,将数据包交给vpn进程并剥掉了UDP头
- vpn进程收到报文之后, 首先解密, 解密后的报文是一个以IP头开始的IP报文,这一步会记录客户端的公网ip地址和udp端口
- vpn 进程将上述IP报文直接写到tun0网卡的fd
- tcp/ip协议栈在处理tun0网卡的数据包时,解析目标IP地址, 然后根据路由选择下一跳地址
- 内核的
conntrack表会记录上一步中的转发信息, 当收到回复包后会根据conntrack表选择将数据交给tun0口 - 之后vpn服务端的处理过程就跟vpn客户端一致,加密后将数据报文还给记录的客户端公网ip和端口, 完成整个vpn通信过程
conntrack 表是整个路由转发的核心,确保vpn数据能够再回到客户端