美文网首页职业经理VPN技术
VPN原理及实现 1:VPN概念及要点

VPN原理及实现 1:VPN概念及要点

作者: 奇林的徒步学园 | 来源:发表于2018-02-06 14:19 被阅读1856次

    系列目录

    引言

    VPN是一种安全的虚拟网络,对它的解释多种多样,有的侧重于隧道封装,有的侧重于访问控制,有的侧重于https,不管怎么说,这些都可以被称为VPN,对于最终用户,他们根本不管自己使用的网络是如何保证安全的,但是对于研发人员,如果不理解VPN的实现方式以及该实现的要点,那就枉做研发了。周末,一个人闲来无事,总结了vpn的种种

    1.最简单的基于https协议的安全访问

    这种方式最简单,也最容易被用户理解,因为它几乎不需要客户端进行任何配置,只需要一个浏览器即可,当然你需要一些外部支持,比如key,比如安装于浏览器的数字证书。这种vpn要点在于它能保护你访问应用期间的数据通道的安全,然而它的局限在于每应用封装的,由于浏览器处理应用层数据,所以每次应用层发起一次访问,安全参数就需要重新初始化一次,OSI模型中,它处理表示层和会话层,可是我们习惯叫它第七层VPN。它保护的是最终的应用通信,而不是自己的主机网络通信。因此这种VPN又叫做SSL VPN。
    所谓的SSL是一种协议,它的原理很简单,它在应用数据进入传输层之前进行了一次加密操作,因此它处于表示层,然而安全参数并不仅仅是数据的安全,还有一项指标是对用户的认证,因此从应用层发起通信到结束通信的所有时间,SSL要保证通信者始终是一开始的那个通过认证的用户,换言之,SSL需要保护一次会话,因此SSL又处于会话层。最新的TLS实际上在OSI模型中和传输层是没有关系的,它本质上还是会话层和表示层的。SSL/TLS握手协议保证了会话层安全,SSL/TLS记录协议保证了表示层的安全。
    SSL协议上的应用访问非常安全,现在很多的购物网站都使用了SSL上的http,也就是https。然而记住,SSL VPN保护的你的应用,而不是你的主机网络协议栈,它的保护粒度很细,一直细到你不可察觉。
    SSL VPN的好处在于其强大的认证机制,PKI体系和SSL简直就是一对孪生兄弟。PKI在互联网上实现了和现实生活中一样甚至更加安全的认证体系。签名验签,数据加密,X.509证书认证等高级主题在PKI中都有描述。而SSL的安全很大程度真是建立在PKI之上的。
    在网络基础设施的意义上,SSL VPN几乎不需要对网络基础设施进行任何配置,它简单的保护了数据,注意,是数据,而不是网络,因此可能你只需要多打一个字符s就能安全访问应用了。这种简便的特定,使得其接入用户指数级的增加。你要明白一个道理,普通用户几乎不知道什么是路由,如果你告诉他们,为了安全,必须配置一条路由,那他们会疯了的,就算客户端软件自动完成了路由的配置,用户可能为了不装客户端而放弃自己的安全性。

    2.IPSec VPN

    在TCP/IP协议栈中,IP协议是主机应用多路复用和解复用的起点和终点,如果能保护IP的安全,那么同一主机的所有的应用程序,换句话说,整个应用层都能得到保护。IPSec就是实现这样的VPN的核心。IPSec为整个IP层提供了保护,我们知道http,ftp,qq等应用可以复用在一个IP上,因此它们都可以得到保护。
    IP层的标识符就是二元组,很简单,那就是源IP地址和目的IP地址,每个这样的二元组定义了一个基本IP流,IPSec保护的就是这种基本IP流,当然在基本IP流之上,还可以有其它的限制条件比如传输层信息,称为扩展的IP流。IPSec将所有的IP流分为两类,一类是感兴趣流,另一类是不感兴趣流,对于感兴趣流,IPSec引擎负责对其进行安全保护,对于不感兴趣流,IPSec引擎直接放过。以上只是IPsec的大致框架,细节上IPSec包含了很多的技术,安全协议包括ESP,AH,IKE,ISAKMP,PKI等,封装技术包括隧道技术,GRE技术,Cisco VTI技术,虚拟网卡技术等,在实现上,很多的开源代码供我们研读,比如FreeSWAN等。本文不再叙述这些技术的细节,需要的话,请参考我前面的文章或者google。
    由于IPSec保护的是IP,因此所有的IP层设备上都是可以实现IPSec的,比如Internet路由器,典型的好处是我们可以实现一个网对网的拓扑结构,这样,多个地理上隔离网络或者子网就可以通过IPSec构建的安全隧道无缝连接在一起,就好像它们地理上在同一个地方一样。IP层的IPSec VPN在这一点上要比SSL VPN具有更强的扩展性,子网内的客户端甚至都不需要SSL协议支持,甚至都不需要有浏览器,直接通过路由将数据导向运行IPSec引擎的路由器,然后该路由器通过配置感兴趣流将包截获,加密封装后发往隧道的另一端。
    网对网的安全通信可能是最符合“虚拟专用网”定义的,因此IPSec技术几乎都被世界上大型VPN厂商所支持,比如Cisco。由于IPSec的这种可用的网对网的特性,它得到了大量的部署,特别是企业级的VPN部署。IPSec的核心在于定义感兴趣流和不感兴趣流,具体区分它们的方式不一而同,可以使用路由的方式,也可以使用filter的方式。

    3.SSL VPN与IPSec VPN

    SSL VPN和IPSec VPN的侧重点不同,前者保护应用,后者保护网络或者主机,前者在应用层实现,后者在TCP/IP协议栈实现。对于访问特定资源而言,建议启用SSL VPN,对于接入特定网络而言,建议启用IPSec VPN,并且阻断其它网络连接以保证内网的安全。
    SSL VPN的精要之处在于和PKI的紧密融合,使得对接入用户的身份认证更加灵活,这是访问控制所必须的,SSL VPN直接控制到应用访问者本身。而IPSec VPN的控制侧重于接入控制,所要认证的信息就是接入端的公网地址以及其被分配的其它标识,而这些都是由ISP控制的,ISP首先保证了第一层的安全,它们往往处于核心网的边缘,因此IPSec的安全性必须和边缘网ISP的安全策略相结合方能保护接入网的通信安全,当然,IPSec亦可以使用PKI来进行接入认证,然而大多数场合没有这个必要,原因正如MPLS不需要加密一样。如果ISP以及核心网不能保证自己客户的安全,那它还能混么?
    SSL VPN亦可以通过代理的方式实现和IPSec VPN相同的功能,然而它还是基于终端安全的。本质上所有的VPN的要旨都在于如何“能截获并加密需要保护的流”,这种截获可以在客户终端完成,也可以在路由器完成,在终端完成的话,可以通过Windows的LSP,Linux的内核Netfilter或者其它类似的技术来完成,以使数据被重定向到自己的第七层应用代理服务器,然后统一由应用代理服务器完成访问,在路由器实现的话,可以使用IPSec的引擎截获感兴趣流,在Linux上可以通过Netfilter的Redirect target截获之,并发往自己的应用服务器或者VTI/虚拟网卡,还可以直接使用路由截获数据,将数据直接导向自己的一个逻辑接口,比如Linux上虚拟网卡,或者Cisco的VTI。不管使用哪种方式,数据包被截获对于客户端用户而言都是不可见的,简化了客户端的配置。

    4.OpenVPN实现的隧道

    前文不断探讨,OpenVPN是一个怪胎,它实现了IP层隧道,可是取却使用了SSL,然而还是要重申,OpenVPN中使用SSL协议仅仅完成了认证功能,并且建立一个可信的,安全的控制通道,OpenVPN隧道的密钥是在这个控制通道中协商的。
    虽然OpenVPN实现了隧道,但是这个隧道却不能和IPSec的隧道兼容。OpenVPN实现server模式,实际上就是一个多对一的服务模式,服务器端通过隧道载荷包的源IP地址来识别特定的客户端,OpenVPN强制使用类似Cisco VTI的虚拟网卡,因此强制使用路由的方式截获感兴趣流,这就意味着,OpenVPN的客户端从虚拟网卡发出数据时,数据源地址必须是虚拟网卡的IP地址,对于主机对网络的拓扑,这没有什么问题,因为路由模块添加源地址的机制会首选和网关处于一个子网的地址,然而对于网对网的拓扑,这就要求OpenVPN的客户端的虚拟网卡上需要强制使用源地址转换。因此最终的目的地将完全丢失访问客户端的IP地址信息,这对透明性打了折扣,特别在访问目的地需要对访问客户端进行基于IP地址的审计的时候。以上,OpenVPN对于网对网的拓扑做的不是那么透明,然而好在它是开源项目,这个美中不足在自己的项目中可以通过定制来解决。本人通过修改代码的方式修正了它,但是在tap桥接模式下有些许问题。
    虽然OpenVPN实现了隧道,然而这个隧道是单向的。OpenVPN可是push下去自己的环境中的许多路由,用于在客户端截获感兴趣流,然而对于网对网双向通信拓扑而言,OpenVPN客户端环境的路由信息却需要在OpenVPN服务器端进行显式配置,这就大大增加了配置的复杂度。一切的原因就是OpenVPN客户端不能push数据到OpenVPN服务器端。好在OpenVPN是一个开源项目,可以定制。代码修改很简单:

    • 第一步:修改options.c的解析push参数的逻辑,使得客户端也可以push数据;
    • 第二步:修改send_push_request的逻辑,将push链表中数据统统发送;
    • 第三步:修改接收push_request消息的函数,此时因为已经认证过了,需要分配给客户端的虚拟网卡的IP地址也已经准备好了;
    • 第四步:保存从客户端发来的路由信息到链表A。在服务器端发送push_reply前从push链表中得到分配给客户端的IP地址B;
    • 第五步:遍历链表A,取出每一条路由C,执行route add C gw B命令;
    • 第六步:第五步的命令执行也可以单独增加一个plugin调用点来通过plugin或者script来完成,完美使用OpenVPN的事件机制。

    上述几个步骤实现起来十分简单,今天周六,我大概用了1个小时实现了它们,然则代码很不规范,不可实用也。
    由此可见,OpenVPN虽然实现了隧道,然而它和IPSec还是有些差距的,然而对其修改和扩展都不会太复杂。OpenVPN实现了很多的机制和策略,使得用户不得不这么做,本质上,我们可以将其定位为适用于主机到网络的拓扑结构的VPN,它被设计出来就不是为了网对网应用的。
    OpenVPN相比无比彪悍的IPSec还是有些优点的,它没有NAT穿越问题,它使用很俗套的TCP/UDP协议,这样对于防火墙更加友好,特别是不需要ISP专门开放支持IPSec。OpenVPN的最大优势还是在于SSL以及PKI,这套安全体系要比ISAKMP好多了。
    最后,OpenVPN让用户在TCP和UDP之间面临这抉择,话说UDP不会导致重传叠加,然而一旦隧道丢包,却需要OpenVPN端系统的Reliability层进行重传,可想而知,这个用户态的实现肯定没有内核态的TCP实现要更好,起码用户态和内核态的切换就是一笔开销。怎么选择,还得从统计数据中得到结果…

    5.MPLS VPN的要旨

    这个VPN一般普通研发人员遇不到,因为它是高度ISP相关的。本质上MPLS就是专用通道,外界的路由注入都不会影响数据包的流向。这个就不多说了。

    6.广义VPN

    说实话,VPN就是一种信息隔离机制,这么说来,不说L2TP,IPSec等,VLAN在LAN中也算是一种VPN,PPPoE 在ISP的LAN中也是一种VPN。只要保证你的网络数据不被窃听,不被篡改,保证这些的底层基础设施都是VPN。所以不要指望能为VPN下一个统一的定义。

    相关文章

      网友评论

      本文标题:VPN原理及实现 1:VPN概念及要点

      本文链接:https://www.haomeiwen.com/subject/ybsgzxtx.html