OpenVPN的历史是坎坷的——从刚刚起步,到广泛使用,再到几乎死亡,然后又回来了。从2006年到大约2009年,开发差距很大,但David Sommerseh(dazo)、Gert Doering(cron2)、Steffan Karger和Samueli Seppänen等开发人员的辛勤工作和奉献精神使该项目取得了成功,并拥有光明的未来。
OpenVPN几乎在所有可用平台上都可用。例如,Snom(一家IP电话制造商)包括一个版本的VOIP电话固件,其中包含OpenVPN客户端。pfSense、OpenWRT和其他WAP/防火墙操作系统包括OpenVPN和(通常)用于管理部署的web界面。
近年来,OpenVPN也在许多手机上可用。第一个是适用于Android的OpenVPN,由Arne Schwabe开发。这使用了一个移植的tun驱动程序,不支持抽头模式(桥接)VPN。
然而,iOS(苹果)的OpenVPN应用程序直到很久以后才出现。股份有限公司花了近一年的时间与苹果公司谈判,以支持外部VPN API,并允许他们访问该API。在Android上,OpenVPN源可以移植到平台上,但由于平台上没有tap驱动程序,因此对tap有一些遗漏。由于iOS上的开发环境,客户端必须从头开始编写。James Yonen在几个月内用C++编写了一个几乎功能完整的客户端,OpenVPN Connect发布到了App Store®。
OpenVPN 2.3比我们最近所处的位置领先了好几光年。快速浏览一下从2008年左右到现在的更改列表,可以看到相当多的重要更新、错误修复和增强。
OpenVPN在很多方面做得很好。OpenVPN是可扩展的、可插拔的和动态的。它具有对IPv6的功能支持,推送默认网关(即使在损坏的网络中),并在保持连接的同时跨公共IP浮动。
跨平台支持在各种VPN实现中无与伦比。
当前版本的OpenVPN存在明显的弱点。首先,整个应用程序被编写为一个单一的单片应用程序。用于客户端连接的二进制文件也用作服务器实例。这不是一个太大的问题,但没有代码的模块化,因此无论应用程序在什么上下文中执行,都需要处理所有的逻辑。
通过解决单片设计难题,开发人员将更容易实现IPv6、其他压缩算法等功能。此外,改进网络堆栈的更改需要在代码中的许多地方进行更新,而不是在单个库或组件中进行更新。这就是为什么现在IPv6和IPv4栈是分开处理的。
通常,在现代硬件上,OpenVPN能够在内核限制将性能降低到不利水平之前支持几百个客户端连接。直到最近高速互联网连接可用,这个限制才成为问题。在过去,一个良好上行链路上的单个OpenVPN服务器可以很容易地与典型家庭互联网连接上的许多客户端连接保持同步。
然而,如今,家里的千兆连接并不罕见,即使在现在不可用的地方,这些高速上行链路也将在不久的将来可用。使用正确的高时钟速度处理器,OpenVPN能够(几乎)使千兆以太网链路饱和。
这需要现代处理器中的AES加密指令(称为AES-NI),如英特尔的酷睿i7和至强E5处理器,以及现代AMD处理器。它还要求将加密密码设置为AES,例如,在服务器和客户端配置中使用 --cipher AES-256-cbc
。
注:无法将加密密码从服务器 push
到客户端。这是OpenVPN当前设计的局限性,希望在未来的版本中得到解决。
操作系统和加密库也在这里发挥作用。大多数服务器设置使用OpenSSL库进行加密和解密。对AES-NI指令集的支持仅包含在OpenSSL 1.0.0中。例如,CentOS 5仍然使用OpenSSL库(0.9.8e-ips),该库不支持这些指令。很容易验证处理器和操作系统是否使用AES-NI指令。使用 openssl speed
命令,您可以快速确定OpenVPN的默认密码(BlowFish或 bf-cbc
)和AES密码(aes-256-cbc
)的加密性能:
x$ openssl speed -evp bf-cbc
[…]
type … 256 bytes 1024 bytes 8192 bytes
bf-cbc … 137977.26k 138565.97k 137470.47k
$ openssl speed -evp aes-256-cbc
type … 256 bytes 1024 bytes 8192 bytes
aes-256-cbc 566760.53k 588199.94k 591250.12k
该测试是在运行Fedora 20的Intel Core i7-4810MQ处理器上运行的,很明显,AES比BlowFish快得多。我们可以安全地得出结论,AES-NI得到了CPU和操作系统的支持。如果我们禁用OpenSSL对AES-NI指令的支持,对性能的影响将非常显著:
xxxxxxxxxx
$ OPENSSL_ia32cap=0 openssl speed -evp aes-256-cbc
type … 256 bytes 1024 bytes 8192 bytes
aes-256-cbc 120009.39k 264001.19k 262821.68k
使用Core i7等处理器,可以在两个方向上实现超过500 Mbps的性能,如第9章“故障排除和调整”所示。
使用 --mssfix
、--tun-mtu
和 --fragment
可以发现其他改进。当一起使用时,可以实现高达400%的速度提升。
其他因素也可能导致OpenVPN之外的性能问题。扩展到千兆速度以上将需要对OpenVPN进行广泛的重新设计,因为它需要一种完全不同的方法来处理如此高的流量。请记住,网络流量通常以1500字节的块(称为最大传输单元(Maximum Transmission Unit ——MTU))进行处理。对于千兆链路,这意味着操作系统内核和OpenVPN进程每秒需要处理大约80000个数据包。在10千兆位的链路上,这增加到超过80万个数据包,即使是最现代的处理器也无法轻松处理。将MTU从1500字节增加到9000字节,也称为巨型帧,可以减少数据包数量,同时不会减少带宽量。巨型帧需要得到网络上所有节点的支持,否则可能会出现数据包碎片。
从2010年开始,开源开发人员开始讨论如何改进OpenVPN服务器流程和提高效率。确定了一些可以改进的领域。幸运的是,这项工作的开始是通过James为iOS应用程序重写客户端代码完成的。即将到来的v2.4和未来v3.0版本的官方路线图可以在以下位置的OpenVPN社区维基上找到:
更具体地说,已经讨论了插件的模块化,甚至使OpenSSL和PolarSSL支持模块。这将允许在其他库可用时更容易地集成它们,甚至可以通过这种方法实现对与SSL完全不同的东西的支持。还考虑了更好的线程和进程卸载,以提高客户端连接量和带宽利用率。
尽管我们已经取得了巨大的进步,但仍有很大的改进空间。一个没有解决方案的关键问题是对开发团队的支持。只有极少数开发人员活跃并致力于该项目。最终的结果是开发周期缓慢,新功能很少。
目前正在研究的一些项目包括更好的IPv6支持、适当的Windows权限分离和TLS漫游。
OpenVPN社区错误跟踪器上提供了当前错误的完整列表。邮件列表中始终欢迎补丁,编写良好且经过测试的补丁肯定会迅速获得批准。链接http://community.openvpn.net/openvpn/report/1直接带您进入打开的bug报告。
从2.4版本开始,OpenVPN将支持不同的机制来压缩VPN流量。目前,仅支持LZO2压缩,但在2.4版本中,您还可以编译以支持Snappy和LZ4压缩算法。这可以大大提高性能,具体取决于VPN上流动的流量类型。普通的web服务器流量将看到很好的性能提升,而难以压缩的流量,如图像或视频文件,由于压缩和解压缩每个数据包的额外开销,可能会看到性能的小幅下降。
在2.3及以下版本中,如果在服务器上启用了压缩,则必须在客户端也启用压缩。事实证明,这在过去很难从客户端日志中识别出来,因为隧道似乎无法通过流量。在v2.4路线图上,有压缩协商。这将允许每个客户端的压缩,甚至压缩协议/算法协商。
在2.4版本中,首次包含了对椭圆曲线认证算法的支持。目前还不可能对所有流量使用椭圆曲线,但它确实允许使用基于ECDSA的证书。
我们希望在2.4版本中也能看到对基于GCM的加密的支持。GCM(Galois/Counter Mode ——伽罗瓦/计数器模式)加密比目前使用的CBC(Cipher Block Chain ——密码块链)加密例程更高效、更高性能。
带关联数据的身份验证加密(Authenticated Encryption with Associated Data ——AEAD)也将在v2.4中首次亮相。
目前,OpenVPN支持使用证书和/或用户名和密码进行身份验证,但要么/要么是不可能的。选项 --client-cert-not-required
实际上完全关闭了证书验证。
在2.4版本中,可以支持使用证书、用户名和密码或两者连接的客户端。这允许在授予用户不同级别的VPN设置访问权限时具有更大的灵活性。为此,添加了一个新选项。
verify-client-cert none
:这实际上与 --client-cert-not-required
相同。verify-client-cert optional
:这将验证客户端提供的证书,但如果验证失败,它不会拒绝连接。verify-client-cert require
:这将验证客户端提供的证书,如果验证失败,则拒绝连接。这将是默认设置,因为它实际上是OpenVPN 2.3版及更早版本的默认设置。--client cert not required
选项将在不久的将来被弃用,并在v3.0路线图中提到。
OpenVPN中的网络代码对IPv4和IPv6代码路径使用单独的功能。几年前,对IPv4的处理方式进行了重大改革,但IPv6的功能从未完成过这项工作。OpenVPN 2.3确实支持完全原生的IPv6传输以及封装的流量。不支持使用IPv6 DNS服务器并从DHCP获取信息,但已在v2.4的路线图上。
push "redirect-gateway ipv6"
也在列表中。您仍然可以通过手动推送特殊路由来模仿IPv6的默认路由:
xxxxxxxxxx
push "route-ipv6 ::/0 2600:dead:beef::1"
OpenVPN目前要求在所有客户端工作站上具有管理权限。拥有独立工作站的用户应该能够在没有管理权限的情况下更新配置,客户端应用程序应该能够接受有效的服务器配置断言。
已经提出了两种方法来实现这一点。其中一个是以Windows为中心的,另一个提供了可以在其他平台上部署或实施的原则。
第一个是通过提供OpenVPN交互式服务来实现的。Heiko Hund于2012年2月首次提出了这种方法(http://thread.gmane.org/gmane.network.openvpn.devel/5685/focus=5728). 该概念包括一个集中式服务,作为另一个OpenVPN进程的包装器。来自交互式用户的客户端连接将启动OpenVPN或OpenVPN GUI,然后该过程将连接到此服务。然后,该服务将从客户端获取参数并创建实际的VPN隧道,建立路由和其他选项。
正确的实现具有以前没有实现或没有真正考虑过的要求。
第二种方法使用两个或三个单独的COM+对象,正如Alon Bar-Lev在2012年3月所建议的那样(http://thread.gmane.org/gmane.network.openvpn.devel/5755/focus=5869). 采用这种方法,需要三个组件:OpenVPN GUI、OpenVPN服务和OpenVPN网络处理器。
OpenVPN GUI与今天相比不会有太大变化。它将继续将任务和更新交给后端流程。由于当前没有权限分离,因此当前的GUI不需要处理任何授权。通过使用COM+和网络OpenVPN模块,GUI可以完全无特权。
在OpenVPN IRC频道和OpenVPN支持论坛上花费了数年时间后,服务器管理用户群中出现了一些反复出现的困难:基本的网络和路由、X.509证书管理以及用户或客户端身份验证。现在读了这本书,你应该对这些概念有了扎实的掌握,并了解了潜在的机制。还讨论了tun和tap虚拟网络适配器之间的差异。
OpenVPN是一个非常活跃的开源项目,并且不断发展。Mastering OpenVPN中的技术和示例在不久的将来可能不会过时。然而,代码中的低效是可以预料的,因此我们强烈建议您阅读手册(手册页),网址为https://openvpn.net/index.php/open-source/documentation/manuals.html.
与大多数开源项目一样,OpenVPN需要更多的帮助——需要更多的志愿者来帮助管理论坛和IRC,还需要更多的开发人员来帮助提高开发速度。有人希望建立一个赏金制度来帮助这项工作。社区很强大,协议得到了广泛认可。
有很多工作要做,但与其他VPN应用程序相比,OpenVPN的功能集使其符合预期。