为什么会有这个项目
在浙大是通过VPN认证上网的,在windows下官方的校园网客户端表现非常好,可以自动解决部分问题,而且不需要什么配置,输入
用户名和密码即可实现一键上网。但是很多同学使用Linux系统,尤其是刚开始学习Linux的苦手,有线网的上网便成为了最大的问题。
当然cc98流传着多种版本的bash脚本,可以通过自动配置xl2tpd和pppd实现一键上网。因为脚本普遍依赖xl2tpd和pppd,所以需要
用户先下载这两个依赖项,但是对于新手,可能很难配置好。于是后来有大神出了deb包,在ubuntu下可以直接下载安装。但是总会
由于莫名的问题,使得小白上网很难。本着如果能做出和windows下一样强大的客户端会有多好的想法,并且可以了解很多VPN底层
实现的想法,做了一些研究。
思路
Linux下有TAP/TUN设备,可以实现虚拟网卡的作用,其中TAP设备是2层设备,可以控制到以太网帧,TUN是3层设备,控制IP包。
例如/tap/tap01
可以视为以太网设备,如果应用程序使用tap01
来发送数据,应用层可以在/tap/tap01
文件中读到以太网帧,
同样也可以在应用层向tap01
设备写入以太网帧,那么侦听tap01
的设备也会受到写入的以太网帧。如下图:
用户模式读取tap01
文件的程序,如果拿到数据包之后,先进行处理,再通过真实网卡发出去,那么就可以实现类似钩子的操作,
对网络数据包进行截获处理。浙大校园网传输时使用L2TP协议承载PPP协议,PPP协议里面是真实的IP数据包,像下图。
但是L2TP数据包自己也要发送出去,它被承载在UDP协议中,从真实本地网卡的1701端口发送到LNS服务器(一般为10.5.1.9)
的1701端口。于是就出现了下图所示的情况,有两个IP报文头,内层IP是内网IP,外层IP是分配给你自己网卡的IP(玉泉校区
的网卡MAC地址和IP地址绑定),所以我们平时有时候内网互相传个文件,想开个FTP或者HTTP传,使用的IP必须是内层的IP。
既然TAP/TUN虚拟网卡可以实现对报文处理后发送,我是不是也可以利用它实现VPN登录客户端呢,想一想应该把正常发送的IP包
外面包装好PPP包,再包装一层L2TP包就可以了。于是便开始了。
L2TP建立
查阅资料以及通过自己抓包(自己使用windows下的校园网客户端抓包)发现,L2TP进行传输前需要以下几个过程来建立连接:
就像WireShark所描述的,最开始是我自己的客户端发送一个SCCRQ消息给LNS服务器(10.5.1.9),这个报文的内容如下:
也可以看出,这些L2TP报文实际发送都是通过UDP,从本地1701端口发送给LNS服务器的1701端口。同时L2TP协议与很多协议
相似,由一个协议头和很多个属性组