基于NDIS中间层驱动的SSLVPN实现
2011-03-14赵春平刘文丽
赵春平 刘文丽
江南计算技术研究所 江苏 214083
0 前言
在SSLVPN中,实现网络访问的通用做法是采用虚拟网卡。Openvpn是这种技术的开源实现,它通过实现一个虚拟网卡将 IP或链路层数据传输到应用层,在应用层通过 SSL隧道通信,以达到安全目的。
本文提出了一种基于Windows NDIS来实现SSLVPN网络访问功能的一种方法,与虚拟网卡SSLVPN不同的是,本方法不需要虚拟IP地址,也不需生成虚拟网卡,它使用真实的物理IP地址进行通信。
本方法借鉴了虚拟网卡方式SSLVPN的思想:实现一个SSLVPN,开发人员需要通过各种手段来截获通信数据,然后将通信数据在SSL隧道中传输。Windows平台下,虚拟网卡工作方式的SSLVPN从根本上讲是将Windows内核态协议栈中的网络数据通过IO控制传递到用户态的SSL隧道中进行传输,它的实现手段是操作系统路由和虚拟网卡。本文介绍的方法通过IO控制将Windows的NDIS层数据传递到用户态进行安全传输。
1 NDIS介绍
NDIS(Network Driver Interface Specification)是微软实现的网络驱动接口规范。它包括NDIS协议驱动,NDIS小端口驱动和NDIS中间层驱动,各种驱动遵循规范进行交互。
通过NDIS中间层可以进行网络数据的截获,NDIS中间层截获的数据为数据链路层数据。
微软的WDK中提供了passThru实现范例,它是一个透明的NDIS中间层驱动。开发人员可以修改passThru范例来达到自己的目的。
在SSLVPN的网络功能中,客户端可以在协议栈的各个层次(需操作系统支持)劫持网络数据,并在用户态的SSL通道中发送。网络层截获从理论上讲应该有三种方法:TDI截获、NDIS截获以及虚拟网卡方式的截获。目前市场上的SSLVPN实现一般都采用虚拟网卡来截获数据,因此有必要来研究基于NDIS截获的实现方式。
2 SSL协议介绍
SSL(Security Socket Layer)协议是广泛使用的安全通信协议。SSL客户端和SSL服务端在socket层协商秘密信息,并在此基础上进行安全通信。
3 实现原理
本方法通过NDIS中间层驱动来劫持和插入网络数据:在发送数据时,通过NDIS驱动和IO操作,将网络数据传递到操作系统用户态,并在SSL隧道中传输;从SSL隧道中接收的网络数据,通过NDIS驱动和IO操作插入到操作系统内核协议栈,如图1所示。
图1 实现原理
数据的发送过程如下:
(1)客户端发送数据时,网络数据被NDIS中间层截获,存入缓冲区;
(2)客户端用户态进程通过ReadFile函数读取NDIS中间层截获的网络数据;
(3)客户端用户态进程通过 SSL隧道发送网络数据给SSLVPN服务端;
(4)SSLVPN服务端将网络数据发送到内部网络。
数据的接收过程如下:
(1)客户端从SSL隧道接收网络数据;
(2)客户端用户态进程通过WriteFIle函数将网络数据写入到NDIS驱动;
(3)NDIS驱动将网络数据插入到协议栈,提交给上层。
为了避免出现环路通信,使 SSL隧道能够正常工作,NDIS中间层必须放过SSL隧道的网络通信。NDIS截获的数据是链路层数据,因此,此种方法能实现SSLVPN的网络访问功能。
4 实现方法
下面给出了主要模块的大致实现方法:
(1)NDIS驱动
NDIS驱动以微软WDK中提供的Passthru范例为基础,增加读写文件操作以及缓存发出的网络数据。在读文件操作中,需要NDIS驱动缓存MPSendPackets中的发送数据,如何缓存以及如何读取,可以参考openvpn的实现方式。在写文件操作中,我们需要构造一个数据包提交给上层协议栈,可以调用 NdisMEthIndicateReceive函数。下面给出了 Ndis驱动最核心的改动代码。
在Ndis发生数据包之前,需要对发出的包进行判定,如果是需要处理的包,则将包进入环形缓冲区。改动如下:
为了用户态进程能够读取环形缓冲区中的数据以及将受到的数据写入Ndis驱动,需要在passthru.c的PtDispatch中增加读写支持,如下:
(2)SSL协议
SSL协议使用openssl来实现。或者也可以使用openvpn的源码,替换其中的虚拟网卡驱动为NIDS驱动,仅做部分修改即可。
5 提高性能的方法
本方法适用于基于NDIS的截获以及基于虚拟网卡的截获方案。用户态进程通过一次 IO操作仅仅只读取和写入了一个数据包。IO操作比较耗时,因此在用户态进程读写的时候,如果尽可能的读写多个数据包,将会极大的提高性能。本方法同样适用于开源的openvpn(开源的openvpn的虚拟网卡驱动中,每次仅读写一个数据包)。
6 总结
通过NDIS中间层驱动实现SSLVPN时,所使用的均为实际的物理地址,一个物理地址即能做到密文通信同时也进行明文通信。
通过NDIS中间层驱动、IO控制以及响应的传输层安全通信手段(比如SSL协议),还能够实现任意两点之间的保密通信。NDIS的截获可以只针对特定目标,完全不影响其他的正常通信。
[1]rfc2246,The TLS Protocol Version 1.0.2009.
[2]WDKDocs_12112009.chm, windows wdk.2009.