SoftEther以前被日本信息处理事业协会勒令禁止使用,相同的还有我们这不便言说的情况。在本文中,我站在部属者和监管者的角度来谈一下VPN技术,最后给出一个我的设计。我可能是个叛教者。
1.OpenVPN怎么样
这是草根DIY的首选。然而不太适合大型企业的大流量。
1.1.OpenVPN的性能问题
1.2.OpenVPN的部署问题
2.全然星型拓扑的优势
它俨然是一个公司内部的局域网,大家都接在一个port足够用的交换机上,这是一个BMA网络,想訪问谁,简单地ARP一下就可以。
3.OpenVPN的可利用的实现细节
那必须是memory BIO实现的TLS以及Realiable层了。
4.实现OpenVPN-ng
新的VPN称作OpenVPN-ng,主要有两个模块组成,分为Switch模块和处理模块,处理模块主要负责VPN数据的加密/解密以及VPN节点间的认证/密钥协商(TLS),而Switch仅仅负责VPN流量的路由和转发,并不涉及加密/解密/认证等。
全部的VPN节点均仅仅和Switch进行UDP通信,流量分为两种,一种是节点间TLS过程的流量,封装在一个控制报文中,另一种是节点间的VPN数据流量,封装在一个数据报文中,两种报文仅仅在报文头部有所区分。报文头部以及通信模型例如以下图所看到的:
能够看到,VPN处理节点之间通过节点ID进行区分而不是通过常规的IP地址以及port号进行区分,这样就形成了一个堆叠在IP地址和port之上的和IP地址以及port号无关的堆叠网络。
4.1.堆叠网络
这个堆叠网络的威力在于它和IP地址以及协议,port号无关。VPN节点之间全然依照VPN节点ID来寻址。这部分任务由VPN Switch模块来完毕。Switch模块中拥有一张{节点ID,IP/port}的映射表。它的效力在于,仅仅要保持VPN处理节点和VPN Switch的连通性,就能够保证节点间的互通。
4.2.VPN处理节点的数据结构
由于一个VPN节点和不止一个VPN节点通信,那么显然每个VPN节点都会保存一个链表,每个链表节点保存一个会话。安全參数包含:
对端节点ID:标示已经建立安全连接的对端VPN节点;
加密算法:比方3DES,AES,RC4之类的对称加密算法;
密钥长度:加密密钥的长度;
摘要算法:MD5,SHA-1等;
哈希长度:摘要计算结果的长度;
主密钥:计算工作密钥的材料;
预主密钥:计算主密钥的材料;
IV长度:...
这个相似于IPSec的SA,简直太像了,假设你懂SA,就知道怎么使用这个数据结构了,对端节点ID用来标示一个链表节点代表的一个数据结构,使用该数据结构的安全參数和对端进行通信。
4.3.VPN Switch的数据结构
VPN Switch上仅仅要保存转发映射表,收到一个节点送来的数据包的时候,仅仅要取出节点ID,查询其{节点ID,IP/port}映射表,就知道数据该发往哪个VPN处理节点。
5.使用BIO而不是网络实现节点间TLS
要明确的是,SSL握手和网络元素是无关的,就像OpenVPN实现的那样,在两个memory buffer之间就能够通过BIO/Realiable层实现TLS协商。如此一来就能够在VPN处理节点之间进行隧道的建立,可是全部的外层IP数据报文统一均发往VPN Switch节点,然后通过这个Switch依据VPN数据包头上标示的内层目标IP地址进行路由查找后转发到正确的VPN处理节点。
6.仅仅是堆叠的Ponitopoint模式的OpenVPN?
非也!这并非多个P2P模式的OpenVPN的简单叠加。注意,OpenVPN-ng中,我显式分离了Switch转发和处理(OpenVPN本身就分离了TLS通道和网络的关系)!因此Switch不再关注包的详细内容,它仅仅是一个简单的转发代理,每个到来的数据包的目的地都是它,它仅仅须要将此数据包buffer始发转发到相应的目的地VPN节点就可以。
隧道是在VPN处理节点之间建立的,可是这个隧道却既不是IP隧道,也不是四层隧道,而是一个应用层隧道,是一个纯粹的buffer隧道,一个buffer到达VPN Switch,作为socker的buffer被读出,这个buffer就是一个加了OpenVPN-ng头部的加密的IP数据报或者一个以太帧,然后依据头部信息进行路由之后,将这个buffer作为一个socket的buffer发送到目标VPN处理节点。
7.信任问题
VPN处理节点信任VPN Switch吗?
VPN处理节点能把全部的密钥托管到VPN Switch吗?
假设能够的话,VPN处理节点就能够分别和VPN Switch建立SSL连接(为了支持移动性,此SSL依旧使用堆在Reliable层上的BIO在远程内存进行,和IP地址无关),然后将VPN节点间协商出来的对称密钥用数字信封传输给VPN Switch,于是VPN Switch就建立了一个n*n的映射,保存每一对VPN处理节点间的对称密钥。
如今想想VPN Switch能做什么?它能够解密每个数据包并处理后再又一次加密。进而能够实现安全审计以及协议转换之类的事情。可是这关乎信任问题,不可小觑。究竟我们该不该信任第三方,究竟有没有权威,这是一个莫大的问题。
8.密钥托管到VPN Swtich
见上一小节。
9.密钥共享到集群
这又是一个扩展。协商出来的对称密钥仅仅在两个节点间共享还是在两个集群之间共享。假设是在两个集群之间共享,那就涉及到密钥怎样共享给集群的问题。这个问题非常多解决方式,数字信封?TLS通道...
10.不动点-终极意义的
这是一个终极意义的不动点,它能够解决移动终端在移动时更换IP的问题。之前我已经用一个自己定义的会话层取消掉了IP地址变化的限制,那么看看我如今的OpenVPN-ng实现,VPN节点之间不再直接建立网络连接,这就意味着,仅仅要VPN节点始终保持和VPN Switch的联通性,VPN节点间的通信就是能够进行的。此时不变的那个点就是VPN Switch!当然了,我须要设计一个状态机,在VPN节点更换IP地址的时候主动上报给VPN Switch一个消息,以便使VPN Switch能够更新其{节点ID,IP/port}映射表。之前我实现的以SID替代IP地址/port作为multi_instance链表的查找键值,那仅仅是攻克了client的IP地址变化问题,可是如今,OpenVPN-ng,不再区分服务端和client,留下的仅仅有VPN处理节点了,它们仅仅和不动点VPN Switch保持连通性,如此一来,哪个VPN处理节点都是任意移动的!
我们来看一下整个网络全部都是移动终端的情况,比方都是手机。
我们来找另外一个不动点,那就是虚拟IP地址。虚拟网卡的IP地址是不变的,尽管移动终端的IP地址在不断变化,可是由于VPN节点和VPN Switch之间一直保持连通性,因此其虚拟网卡的IP地址不会变化,因此在这些虚拟网卡的IP地址之间建立的TCP连接将会保持,不会因移动终端本身的IP地址变化而中断。是不是有点像LISP(注意,不是Lisp语言,而是位置标识分离协议)的思想呢?
11.为移动续航
这篇文章我已经写了好几周了,过去的8月份,实在太忙,先是上旬差点儿都是在出差,只是那算是好的,由于短短的几天居然学会了非常多东西,接下来的中旬和下旬就是悲哀了,反复性的技术支持让我居然好几次想摔了我的iPhone5,断断续续一直在思考怎样让移动终端在移动时支持全然的平滑过渡,可是仅仅是想象一下而已,由于我知道这个OpenVPN-ng是不会被採纳的...再后来,由于要为小小上幼儿园作准备,家长会,家訪,...又是短短的时间,让我明确了非常多的世态炎凉,抽了几个夜晚,我把OpenVPN-ng实现了出来。
OpenVPN不仅仅能够加密数据,另一个特性,它有自己的协议,并且是应用层协议,用该协议封装了一个IP数据报或者以太帧,这就使应用层隧道成为可能,然后它使用虚拟网卡以路由的方式捕获数据包到应用层,这就能够将IP数据报或者以太帧在应用层完毕协议封装,一切通信全都环绕虚拟网卡的IP地址进行的话,移动便不再是问题了。然而要寻找一个Switch作为不动点,它就像航空母舰一样,仅仅是它在为移动性续航!这样的中心化的移动性策略非常简洁,起码我是这么觉得的,非常适用于一个单一的移动环境。