VTun 工作原理详解
转载自:http://blog.csdn.net/wangxing1018/article/details/4169179
写在前面:开源项目VTun 短小精悍,涉及到了Linux下网络编程的几乎所有的东西,包括守护程序、信号的处理、服务创建子进程等,实现了虚拟LAN的功能。个人感觉 VTun 唯一的缺憾是在认证方面,没有基于X509证书,而是简陋的在配置文件进行了密钥的设置。虽然在舍弃CA方面,做到了“轻型化”,但留下来极大的安全隐患,这也限制了它的应用,使得其只适合进行一些实验和测试。
我参考了 VTun 源代码和 麻利辉在ibm的developerworks 文章,把自己对 VTun 工作原理做了一个简要的叙述。限于水平,文章难免谬误,仅供参考。欢迎指正!
1. 初始化
这一个阶段主要是服务器和客户端的为下一阶段的通信做各种初始化和准备工作,依次包括建立连接、挑战 /握手认证、设置 TAP/TUN 设备等。
初始化阶段
如图可以看出,这一阶段还没有用到虚拟网卡 TAP/TUN 设备,服务器和客户端所有通信均通过物理网卡eth0 进行,双方会开启 socket 网络套接字进行挑战 / 握手认证双方合法性。注意 :挑战 / 握手所需要的密钥在配置文件 vtund.conf 给出(字段是 pass XXXX ),还有我们会注意到在源代码中的认证还需要 host (在 auth.c中)
if( !(h = find_host(host)) )
break;
此处的 host 就是在 vtund.conf 中的服务器端给客户定义的名字(服务器端可以任意取)。
接下来,服务器和客户会根据各自的配置文件设置虚拟网卡的特征,比如是 TUN 还是 TAP ,或者 PIPE 、TTY ,配置虚拟网卡的网络地址和内核的路由等。
好了,我们假设以上一切顺利了。现在,万事俱备、只欠东风。下面就是重头戏,主角虚拟网卡出场了。
2. 虚拟隧道通信
这一阶段基本进入了正题,服务器端和客户端的应用程序可以使用虚拟网卡进行加密通信了。
虚拟隧道通信
下面就上图的做一个说明。这里我们假设:
VTun 服务器: IP : eth0 192.168.1.11 tun0 10.0.1.1
VTun 客户端: IP : eth0 192.168.2.22 tun0 10.0.1.2
(关于VTun的配置可以参见 关于VTun建立IP隧道的配置文件中的网络配 置 )
1. VTun 客户端 的应用程序要和 VTun 服务器的应用程序 进行通信,发往 服务器 的数据报的出口为 tun0设备。数据包的源 IP 10.0.1.2 ,目的 IP 192.168.1.11 (目的地址也可能为 10.0.1.1,这要看应用程序说提供服务的IP 。如果是 IP 192.168.1.11 ,那么还要有网关gw 10.0.1.1帮忙转发,才可以滴 );
2. 虚线表示 VTun 进程 read 读取 tun0 设备的数据,不走TCP/IP协议栈。而读取的数据为IP包(另,在TAP的是以太网帧 ) ;
3. 隧道封装。VTun 进程对读到的数据进行对称加密,然后 write 写到 socket 套接字描述符,通过物理网卡,发送到通信对端。(数据包的源 IP 192.168.2.22 ,目的 IP 192.168.1.11 ) 。这样一来,就形成了加密隧道包裹的情形了。TUN的是IP-in-IP,TAP的是ETH-in-IP ;
4. 数据包正常路由;
5. 隧道解封装。 在 VTun 服务器, VTun 进程 read 读取 socket 套接字描述符,然后进行对称解密;
6. 虚线表示 VTun 进程将解密后的数据 write 写到 tun0 设备;
7. tun0 设备将数据包交给TCP/IP协议栈处理。或者转发,或者递交到上层应用,比如 VTun 客户端的应用程序收到数据。
总结 :
VTun 的一个优点就是在用户区,即使崩溃了也不会影响系统内核。注意:由于封装隧道的缘故,数据包在整个过程中, IP 报头和 TCP 或 UDP 头都没有被修改,因此不惧 NAT 和源路由过滤。因为只是添加了一条到 tun0设备路由而已,可以说是以最小的代价完成了数据报的 “ 乾坤大挪移 ” 。