aben1223
驱动小牛
驱动小牛
  • 注册日期2004-11-29
  • 最后登录2007-06-01
  • 粉丝1
  • 关注0
  • 积分1000分
  • 威望201点
  • 贡献值0点
  • 好评度192点
  • 原创分2分
  • 专家分0分
阅读:5890回复:3

贡献一下,近日虚拟网卡和openvpn的心得(感谢cyliu和jxxy1234)

楼主#
更多 发布于:2007-05-08 17:38
虚拟网卡和openvpn
    虚拟网卡可以用很多方式来实现的,据我的了解,Mux是一种方法,OpenVPN中的tap_win32也是一种方法。其他的譬如ds自带的vnic的例子,还有Cipe(据说是和OpenVPN是同样的原理,比较简单就对了)。在这边我了解得比较多的是Mux和OpenVPN。重点介绍OpenVPN。
    MUX是NDIS下一个IMD的网络驱动。能虚拟出多个网卡,他和OpenVPN实现的方式不同。MUX是中间层的和Passthru一样。而OpenVPN的tap_win32是在Miniport层下虚拟出网卡的。看过MUX的代码,MUX下的多个网卡之间相互通信的方法是通过一个全局的AdapterList,其中通过里面每个Adapter的BindingHandle和MiniportHandle进行数据包的发送和接收。
    而OpenVPN是从Miniport这一层虚拟出一个网卡。这样他就不能用MUX的方式来将数据包在两个或者多个网卡之间进行传送。它是通过应用程序来执行的。下面我将介绍OpenVPN的实现方式,基本上所有的VPN都是这么实现的。
1.    更改路由表,通过应用程序调用API函数更改和添加路由表。将数据包都先发送到虚拟网卡。
2.    虚拟网卡得到数据包,先判断该数据包是什么类型的数据包。因为本身是一个物理的虚拟网卡,它必须去处理ARP,DHCP等一些数据包,用于欺骗上层网络,否则该网卡将不能工作,这一点比IMD的驱动要麻烦一些。
3.    虚拟网卡判断得到的数据包是普通的Tcp和Udp数据包后,将该数据包压入一个堆栈。该堆栈是一个和应用程序(通常这个应用程序被称为守护程序)共享的内存块。然后驱动Set一个Event。上层应用程序Wait这个Event。并从这个堆栈中取得这个数据包。
4.    上层应用程序得到这个数据包后,修改修改这个数据包的内容,然后建立一个Socket把该数据包重新封装成TCP或者UDP包后从物理网卡发送到Vpn的服务器上,由服务器再进行处理。转发到最终的目的IP。
假设我们要打开一个IE,那么数据包的路线如下所示。
ie-vnic-vpn client-tcp/udp-vpn网关-route-web服务器
    接收的时候正好相反。
    
NetPas就是利用OpenVPN来实现的,基本上在客户端上没做任何的修改(据说OpenVPN是不允许这样投入到商业用途当中,否则会被告的)。
    这里有几个比较扰人的问题,我提一下。在看tap_win32代码的时候,里面有很多关于ARP,DHCP,TUN的代码,一直看不太懂,觉得没有用想删掉。因为以前我做过Miniport的驱动程序,不需要对这些数据包进行特别的处理的,但是这是一个虚拟网卡,它不能像正常的网卡一样发送和接收。所以必须对这些数据包进行处理并返回结果用于欺骗上层网络,否则该网卡不能工作。
    还有一个问题,就是使用VPN的虚拟网卡,会产生一对IP,都是以10开头的。举个例子,每次Netpas登陆以后,都会产生这样一对IP:10.103.160.173和10.103.160.174。这一对IP每一次登陆都不同,但前三个字节都相同,最后一个字节也都只差1。其中一个就是该虚拟网卡所分配的IP,另一个是所谓的DHCP_SERVER。但是其实这些都是虚假的,VPN所有关于网络的设置都是虚假的,比如路由,ARP或DHCP。因为根本就不需要做成真的,数据是两个app间直接通信,根本就不是通过物理通信协议的那种普通的通信方式。
    现在要连通这个虚拟网卡,将这个虚拟网卡从断掉连接的状态变成连接的状态进行正常工作,现在只需要配置一台LINUX的VPN服务器。敲入一些命令就行了。
    还有一些问题还没解决。
1.    那一对IP是怎么生成的,听人说这个IP地址是通过服务器直接指定的,指定ip地址的数据报是直接传递给client的。这一段代码我还没看到。
2.    还有LINUX下的那个VPN服务器是怎么处理这个数据包的。修改还是去掉封装发送出去。关于LINUX服务器段的程序我还没看过,这个也还不太清楚。
3.    LINUX没碰过,虽然网上介绍配置的内容很多,但是还有要发一定的时间接触接触。



总结一下,openvpn原理如下:
1 openvpn驱动部分实现了网卡处理和字符设备。网卡处理网络数据,字符设备完成与应用层的数据交互。
2 使用openvpn必须修改路由表
工作过程 发送数据:
1 应用程序发送网络数据
2 网络数据根据修改后的路由表把数据路由到虚拟网卡
3 虚拟网卡把数据放到数据队列中
4 字符设备从数据队列中取数据,然后送给应用层
5 应用层把数据转发给物理网卡
6 物理网卡发送数据

接收过程:
1 物理网卡接受到数据,并传到应用空间
2 应用守护程序通过字符设备,把数据传给驱动网卡
3 数据通过虚拟网卡重新进入网络堆栈
4 网络堆栈把数据传给上层真实的应用程序。

最新喜欢:

TOMG2004TOMG20...
周维彬
hammly
驱动牛犊
驱动牛犊
  • 注册日期2007-04-02
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分150分
  • 威望16点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-05-08 21:20
楼主,能帮忙讲下MUX是怎么实现虚拟网卡的么?
我是初学者,已经看了1个月NDIS了,还是很迷茫
aben1223
驱动小牛
驱动小牛
  • 注册日期2004-11-29
  • 最后登录2007-06-01
  • 粉丝1
  • 关注0
  • 积分1000分
  • 威望201点
  • 贡献值0点
  • 好评度192点
  • 原创分2分
  • 专家分0分
板凳#
发布于:2007-05-09 09:28
http://www.cnblogs.com/5tao/archive/2006/07/04/442826.html
今天终于配好我的第一个openvpn了 而且已经可以用了
方法参照上面连接

虽然说很多具体的还不懂,但是这个应用已经会了
算是一个进步
周维彬
mayin_15
驱动牛犊
驱动牛犊
  • 注册日期2002-12-24
  • 最后登录2021-08-27
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望32点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2007-05-09 15:03
谢谢楼主的分析,不过感觉VPN最终还要通过应用层把包通过物理网卡发出去这种方式太影响效率,感觉从内核层中封包直接发出去比较好。
小帅厨
游客

返回顶部