第九章:故障排除和调整

通常,使用OpenVPN设置VPN非常容易。与其他VPN解决方案相比,这是OpenVPN最具吸引力的功能之一。然而,有时有必要对不工作的设置进行故障排除或调整现有设置以获得性能。

OpenVPN的故障排除和调优经常被忽视。客户端和服务器端的OpenVPN日志文件提供了大量信息,但你必须知道如何读取它们。在设置客户端和服务器配置文件时,也会犯很多常见错误。在本章中,您将学习如何解释OpenVPN日志文件,以及如何检测和修复其中一些常见错误。

最后,工作设置和工作良好的设置之间存在很大差异。您的OpenVPN设置可能运行正常,但用户仍可能抱怨性能不佳。从OpenVPN设置中获得最大性能似乎是一种魔法。在本章中,你将学习一些这种黑魔法。

本章将涵盖以下主题:

如何读取日志文件

测试一个不工作的设置起初似乎是一项艰巨的任务。你该从哪里开始?

幸运的是,OpenVPN提供了出色的日志记录和调试功能。然而,随着日志记录的冗长程度增加,读取这些日志文件也变得越来越困难。

OpenVPN的默认日志级别为 1 ,但建议将详细程度设置为 3 。这通常会为管理员提供足够的信息来检测设置问题,同时将性能损失降至最低。

建议仅在出于测试的目的时,将详细程度设置为 5 或更高,因为这会严重影响性能。

到目前为止,这本书中的每个例子都包含了设置 verb 3 。首先,我们将仔细检查客户端和服务器日志文件,以获得这种冗长的工作设置。了解甚至可能存储工作连接的日志非常重要。当试图在非工作设置中查找错误时,将非工作案例的日志文件与工作设置的日志文件进行比较非常有用。

使用默认配置文件 basic-udp-server.conf启动服务器:

先不要连接客户端。服务器日志文件现在将包含以下内容:

为了清楚起见,每行前面的时间戳都被缩写了。

让我们逐行浏览这个日志文件:

接下来,我们启动客户端并查看服务器端日志文件:

之后,我们还将浏览客户端日志文件:

让我们浏览一下新的日志条目:

同样,这是客户端日志文件(注意时间戳,并将其与服务器日志文件中的时间戳进行匹配):

让我们浏览一下新的日志条目:

检测非工作设置

OpenVPN设置可能会因多种原因失败。在下一节中,我们将介绍一系列常见故障。首先,让我们看看连接尝试失败时日志文件中显示的内容。失败可能发生在连接尝试的早期,甚至在 Initialization Sequence Completed行之后。

如果我们使用了错误的 tls-auth 文件,连接将很早失败。这正是使用 tls-auth 的原因,因为当流氓客户端尝试访问时,它将最大限度地减少OpenVPN服务器的负载。尝试连接而不指定 tls-auth 文件的客户端将在服务器日志中显示如下:

由于OpenVPN服务器立即拒绝连接尝试,因此没有关于此客户端的其他报告。从日志文件中的时间戳可以看出,客户端在每次连接失败时都会增加连接尝试之间的延迟时间。如果60秒内无法建立连接,则客户端将中止:

只有在连接似乎已成功初始化后,第二次连接失败才会变得明显。为此,我们指定在一侧使用不同的加密密码,但忘记在另一侧使用。客户端日志文件现在将显示以下内容:

因此,起初连接似乎已经成功建立(第1至3行),但10秒后,数据信道加密和解密失败。

注:如果在这种情况下使用了Windows GUI,GUI图标将变为绿色,但VPN本身将无法运行!

在初始化过程中,大多数配置问题将在服务器端或客户端报告。路由问题更为常见,OpenVPN通常不会报告。因此,需要不同的故障排除技术。

修复常见的配置错误

在设置OpenVPN配置时,有一些常见的错误很容易犯。这些配置错误大致可分为四类:

在本节中,我们将介绍其中的前三个类别。本章稍后将讨论路由错误。

客户端配置中的CA证书错误

客户端配置文件几乎总是包含如下三行:

这些证书和私钥文件在第3章“PKI和证书”中创建,并在后续章节中广泛使用。

但是,CA文件不需要指定用于对客户端证书文件进行签名的证书颁发机构。它必须是用于签署服务器证书的证书颁发机构的公共证书。如果服务器证书由其他CA签名,则客户端将拒绝连接到服务器。这可以在客户端日志文件中看到:

在这种情况下,服务器端不会记录任何错误,因为服务器认为客户端证书是有效的。

服务器上唯一记录的内容如下:

这显示了OpenVPN客户端连续进行的连接尝试。

如何修复

确保在客户端配置文件中指定了正确的CA文件。

服务器无法识别客户端证书

如果服务器无法识别客户端证书,服务器将拒绝访问它。如果使用了错误的(或恶意的)客户端证书,或者客户端的证书被吊销,并且在服务器配置文件中指定了 crl-verify 选项,则可能会发生这种情况。

如果未知客户端尝试连接到OpenVPN服务器,以下条目将显示在服务器的日志文件中:

服务器无法验证客户端的证书,因为它无法识别用于签名的CA证书。因此,它拒绝允许此客户端连接。

在客户端,60秒内日志文件中不会打印任何消息,之后初始握手超时并进行新的连接尝试:

如何修复

确保服务器能够识别客户端的证书。这可以通过在服务器配置文件中指定正确的CA证书来实现,也可以通过将CA证书添加到服务器配置文件的堆叠CA证书文件中来实现:

接下来,在服务器配置中使用以下内容:

这样,服务器将接受由 CA1.crtCA2.crt签名的客户端证书。

当然,如果这是一个试图连接的流氓客户端,那么更合适的解决方案可能是将客户端连接的IP地址列入黑名单。

客户端证书和私钥不匹配

如果客户端上的证书和私钥不匹配,那么OpenVPN甚至不会尝试连接到服务器。以下错误将打印在日志文件中:

当证书和私钥更新时,尤其会出现此问题;将旧私钥与新证书一起使用是一个常见的错误。

如何修复

确保客户端的证书和私钥匹配。令人惊讶的是,没有易于使用的工具。为了确定证书和私钥是否属于一起,我们可以使用以下命令并查找模数部分:

如果我们仔细查看公钥(证书)和私钥的模数,我们可以看到它们是相等的。因此,此证书和私钥属于一起。

贴士:在比较模数时,比较前几个字节和后几个字节通常就足够了。

auth和tls-auth密钥不匹配

authtls-auth 选项用于使用HMAC签名算法对控制通道和数据通道数据包进行身份验证。auth HMAC算法的默认值是 SHA1 ,它使用160位密钥。tls-auth 选项没有默认值,因为它不是必需的。但是,建议使用此选项,因为它提供了额外的DDoS攻击防护层。

如果客户端和服务器配置中指定的 auth 算法不匹配,则服务器将不允许客户端开始TLS安全握手。同样,如果客户端和服务器上的 tls-auth 文件不匹配,或者如果任何一方给出了错误的 direction 参数,那么服务器也将不允许客户端开始TLS安全握手。

通常,在服务器配置文件中指定以下选项:

相应地,在客户端上,我们有以下选项:

这里,第二个参数定义了所使用的 tls-auth 密钥的 direction 。此参数不是必需的,但它允许OpenVPN对传入和传出流量使用不同的哈希(或HMAC)密钥。客户端上用于对传出流量进行签名的密钥必须与服务器上用于验证传入流量的密钥匹配,反之亦然。

如果使用了错误的 tls-auth 密钥文件,或者省略了方向或未正确指定方向,则服务器日志文件中将显示以下条目:

与此同时,客户端将在超时发生之前尝试连接60秒。

如何修复

确保在客户端和服务器配置文件中使用相同的 tls-auth 文件。此外,请确保在两端正确指定了方向参数(如果使用的话)。

如果您仍然不确定哪些HMAC密钥用于传入和传出连接,可以增加日志文件的详细程度,以查看客户端和服务器都使用的实际密钥。让我们将以下内容添加到客户端和服务器配置文件中:

现在,双方将在启动时打印出大量日志信息。日志文件中要查找的行位于服务器端:

HMAC size=20 行对应于使用 SHA1 的160位消息哈希的事实,因为160位与20字节相同。

如果在客户端使用了正确的 tls-auth 文件和方向(direction)参数,我们将发现以下内容:

传入和传出的控制通道身份验证密钥在客户端和服务器上镜像,以确保正确的TLS身份验证。

MTU大小不匹配

OpenVPN使用两种最大传输单元(Maximum Transfer Unit——MTU)大小:

tun-mtu 参数的默认值是1500字节,这也是以太网适配器的默认mtu大小。在正常情况下,我们可以使用以下公式从 tun-mtu 大小计算link-mtu 大小:

在这里,constant 取决于所使用的配置选项。在影响此常数的配置选项中,我们有以下选项:

如果我们看到 link-mtu 警告不匹配,这通常表明客户端和服务器配置文件中的其他地方配置错误。正如您将在后续示例中看到的,客户端和服务器之间的 link-mtu 不匹配可能会经常发生。通常,如果 link-mtu 不匹配,VPN连接将无法正常运行。

小贴士:通过明确设置来抵制修复 link-mtu 警告本身的诱惑。首先,修复可能导致 link-mtu 警报出现的其他警告。

在调整VPN连接时,link-mtu 参数也很有价值。为了从VPN连接中获得最大的性能,我们需要确保数据包不会被操作系统碎片化,因为这将对性能产生巨大影响。特别是在基于卫星的链路上,这可能会使性能几乎停滞不前。

如果在服务器端指定的MTU大小与客户端不同,则日志文件中将显示以下警告:

这表明,对于一个相当 default 的配置,link-mtu 开销实际上是41个字节。在这里,我们在客户端配置文件中添加了:

此时,VPN连接将正常工作。然而,由于数据包需要分段和重新组装,性能将受到限制。通过发送设置了 do not fragment 标志的大型ICMP数据包,可能会触发此设置的错误。在Linux/FreeBSD上,可以使用以下命令完成此操作:

在Windows上,我们使用以下内容:

这将导致 ping 命令100%的数据包丢失,它也会显示在日志文件中:

这个错误消息起初可能看起来很混乱,但它是由发送方构造并签名了一个大于1400字节的数据包这一事实引起的。客户端仅接收此数据包的前1400个字节并检查签名,但失败。然后,它拒绝该数据包并打印出错误。

如何修复

如果要使用 tun-mtu 选项,请确保在客户端和服务器配置文件中都指定了该选项。

密码不匹配

用于OpenVPN数据通道的加密密码可以通过使用以下选项指定,默认设置为 BF-CBC

如果客户端配置文件中指定的密码与服务器配置文件中的密码不同,则双方的日志文件都会打印出警告消息,但VPN连接会出现。然而,一旦任何流量通过它,它将无法解密。我们可以在客户端日志文件的以下摘录中看到这一点:

最初打印的三个警告显示了所使用密码的不同类型和不同 size 。默认的Blowfish密码使用128位强度,而AES-256密码使用256位强度,导致加密数据包稍大(Blowfish的 link-mtu 为1541字节,AES-256的 link-mtu 为1557字节)。

如何修复

确保在客户端和服务器配置文件中指定了相同的密码。由于客户端和服务器日志文件都会打印出预期的密码,因此这是一个相对容易修复的错误。

注:目前无法将密码从服务器 push 到客户端。这是OpenVPN开发人员的愿望清单,但它对代码有重大影响。在版本2.4甚至2.5之前,它不会被添加到OpenVPN中。

压缩不匹配

OpenVPN能够压缩所有正在运行的VPN流量。对于某些类型的流量,如普通网络流量,这可以提高VPN的性能,但确实会给VPN协议增加额外的开销。对于不可压缩的流量,此选项实际上会略微降低性能。

当前用于指定压缩的选项如下:

请注意,我们不需要指定第二个参数。如果使用压缩,默认值是 adaptive

正如我们将在第10章“未来方向”中了解到的那样,这个选项将被一个更通用的 compression 选项所取代,允许不同的压缩机制。

可以将 compression 选项从服务器推送到客户端,但前提是在客户端配置文件本身中指定了压缩选项。如果客户端配置文件不包含此选项,则VPN连接将失败。客户端日志文件将显示以下内容:

服务器日志文件将列出相同的 WARNING 消息,还将显示解压缩警告:

注:奇怪但真实的是:如果我们等待足够长的时间,客户端将由于压缩错误而重新启动,并尝试重新连接。然而,这一次连接将成功,因为 comp-lzo 选项仍位于内存中。

如何修复

如果要使用压缩,请确保在客户端和服务器配置文件中都指定了 comp-lzo 选项。通过客户端配置文件中的 comp-lzo 选项,我们现在可以使用 push 选项控制服务器端使用的压缩类型。使用以下内容:

这将关闭压缩,但不幸的是,这与根本不指定任何压缩方法不同。希望在未来的版本中解决这个问题。

片段不匹配

最常用的调优参数之一是 fragment 选项。您将在本章稍后的“如何使用ping和iperf优化性能”一节中了解有关此选项的更多信息。

comp-lzo 选项一样,fragment 选项不需要在任何一侧指定。然而,我们不能只从一个方面来具体说明;必须在两者上都进行配置。如果仅在一侧指定,则必须在另一侧指定。从技术上讲,甚至没有必要为两侧的 fragment 选项使用相同的值,但建议使用。

如果客户端未指定 fragment 选项,但服务器端使用了该选项,则VPN连接将无法正常运行,如客户端日志所示:

同样,它看起来好像VPN已经启动(Initialization sequence completed 初始化序列完成),但日志文件将充满 code=22 错误消息。

请注意,警告实际上列出了 mtu-dynamic ,这是此功能的弃用名称。

如何修复

如果要使用 fragment 选项,请确保在客户端和服务器配置文件中都指定了它。

请注意,与 comp-lzo 选项不同,此功能不能从服务器推送到客户端。

tun 与 tap 不匹配

使用 tap 式网络最常见的用例是桥接设置,正如我们在第6章“tap设备的客户端/服务器模式”中所了解到的那样。然而,并非所有设备都支持轻触式网络。最值得注意的是,所有Android和iOS设备都缺乏这种功能。因此,如果我们将这样的设备连接到 tap 式OpenVPN服务器,服务器日志文件将列出来自这些客户端的警告:

除了这些警告之外,服务器将不会检测到有关连接客户端的任何信息。在客户端上,类似的警告将与此警告一起列出:

由于我们无法在分接式设置中推送子网拓扑,客户端将回退到默认的Net30式网络。这种类型的网络本质上与分接式网络不兼容,但除此之外,客户端不会列出任何警告或错误。

即使我们(错误地)添加拓扑子网来抑制客户端上的此警告,VPN仍然无法正常运行。

如何修复

确保两侧使用相同类型的网络(tun或tap)。如果你必须使用Android或iOS设备,那么你必须设置一个tun风格的服务器配置,因为这些操作系统不支持tap风格的网络。

client-config-dir 问题

在第4章“使用tun设备的客户端/服务器模式”中,我们在“客户端特定配置-CCD文件”一节中了解了CCD文件及其用途。CCD文件通常用于通过 iroute语句将客户端局域网连接到服务器网络。

OpenVPN邮件列表和论坛上的经验表明,客户端配置目录选项容易出错和配置错误。造成这种情况的三个主要原因如下:

normal 的日志级别下,如果OpenVPN无法找到或读取CCD文件,它不会抱怨。它只是将传入连接视为标准连接,因此永远不会达到所需的 iroute 语句。

调试此问题的最简单方法是在服务器配置中临时添加一个额外选项:

重新启动服务器,让客户端尝试重新连接。如果服务器无法读取连接客户端的相应CCD文件,它将拒绝访问。如果发生这种情况,我们知道CCD文件尚未被读取。如果客户端可以连接,那么就存在另一个问题——很可能是路由问题。

查看OpenVPN服务器如何处理CCD文件的另一种方法是将日志级别增加到 4,并重新连接列出CCD文件的客户端。证书 /CN=client1 的客户端的CCD文件内容如下:

这指示OpenVPN服务器将VPN IP地址 10.200.0.99 分配给此客户端,并通过此客户端路由子网 192.168.4.0./24。服务器日志文件现在列出了以下内容:

如果突出显示的行不存在,则不会读取CCD文件。此外,以 MULTI:开头的下一行显示了OpenVPN服务器如何解释CCD文件中的行。这对于进一步调试任何 iroute 问题非常重要。

如何修复

如果服务器进程无法读取CCD文件,请检查文件完整路径的权限,包括指向该文件的所有子目录。确保使用 user 选项指定的用户有权读取所有目录和CCD文件本身。

确保 client-config-dir 选项列出的是绝对路径,而不是相对路径。此外,如果我们使用 chroot 选项(有关详细信息,请参阅手册页),请确 client-config-dirchroot-jail 中可见。

使用 ccd-exclusive 选项快速确定OpenVPN是否可以读取ccd文件。如果可以,那么增加服务器端的日志级别,看看OpenVPN如何解释CCD文件中的语句。

在Linux中无法访问tun设备

如果OpenVPN启动时权限不足,或者OpenVPN设置为放弃root权限并切换到另一个 userid(例如,nobody),那么对 tun 设备的访问可能会丢失。如果OpenVPN用于虚拟化环境,如OpenVZ或虚拟专用服务器(Virtual Private Server ——VPS),也可能发生这种情况。

如果OpenVPN启动时权限不足,则VPN连接根本不会出现:

在启动OpenVPN之前,请检查 userid 或使用 sudo 切换到特权用户。

当权限不足时,更常见的情况是在VPN连接自动重启后。考虑以下客户端配置文件:

这是在底部添加了两行的基本配置文件。当我们使用此配置文件启动VPN连接时,连接正常,但会打印一条警告:

事实上,在需要重新启动VPN连接后(例如,由于网络连接不良),重新启动将失败:

在这里,我们看到OpenVPN无法重新启动,因为用户 nobody 被允许读取用于此连接的私钥。如果我们指定了一个具有正确权限的用户,我们会看到一个不同的错误:

请注意,在重新启动期间,OpenVPN无法关闭现有的 tun 设备或删除任何系统路由。如果使用 persist-tun ,也会出现这种情况,但在这种情况下,它是无害的。

如何修复

如果您也使用 user 和/或 group 选项,请将以下选项添加到客户端配置文件中:

确保您以足够的权限启动OpenVPN。

此外,请确保OpenVPN具有正确的SELinux安全上下文,或者尝试在SELinux设置为允许或禁用模式的情况下运行OpenVPN:

Windows中缺少提升的权限

对于某些旧版本的Windows版OpenVPN安装程序,没有为OpenVPN GUI应用程序设置正确的权限。

对于这个特定的例子,从OpenVPN服务器向所有客户端推送了一条路由:

在Windows Vista及更高版本上,OpenVPN需要提升权限才能添加或删除系统路由。如果这些权限不存在,VPN通常会正确初始化,GUI图标将变为绿色。

我们甚至可以ping OpenVPN服务器的VPN服务器IP地址。但是,OpenVPN GUI中的日志文件将显示一些错误。

第一行实际上很棘手:

棘手的部分是,一旦我们点击 Disconnect 按钮,日志就会消失,因为它无法写入磁盘!这是由于默认日志目录 C:\Program Files\OpenVPN \log 只能由具有提升权限的用户访问。

日志文件中的最后几行告诉我们,OpenVPN无法添加服务器推送的路由。同样,这是由于OpenVPN程序在运行时权限不足造成的。

如何修复

使用提升的权限(启用以管理员身份运行)重新启动OpenVPN GUI后,路由被正确添加。这可以从路由表中看出:推送的路由 192.168.122.0/24 现在存在于路由表中,使用服务器的VPN IP地址 10.200.0.1 作为网关。

解决路由问题

OpenVPN电子邮件列表和用户论坛上提出的大多数问题实际上都是路由问题。设置VPN连接是一回事,但将其集成到现有网络中则是另一回事。对于新手来说,困难的部分是看OpenVPN在哪里停止,路由从哪里开始。本节旨在作为一个逐步指导,以解决相当基本的OpenVPN设置中的路由问题。

考虑以下网络计划:

为此,在主办公室设置了一个OpenVPN服务器,员工作为常规VPN客户端连接,而辅助办公室作为特殊客户端连接,公开了自己的网络。

绘制详细图片

在为OpenVPN创建配置文件之前,请绘制网络布局的详细图片,包括所有子网、IP地址、网关IP地址、接口名称等。

使用的公共IP地址未在此图片中列出,但建议这样做。此外,来自在家工作的人的连接也不包括在内,但他们将连接到上图中 gateway1 的公共IP位址。

gateway1 上,添加了一个端口转发规则,因此端口 1194 上的传入和传出UDP流量被转发到 172.31.1.2:1194 的OpenVPN服务器。

由于我们需要在二级办公室披露网络,我们还需要使用带有适当 iroute 语句的 client-config-dir 文件。

此设置的服务器和客户端配置文件已在第4章“带tun设备的客户端/服务器模式”中列出,但有一些细微的IP地址更改。新的配置文件集如下:

此文件保存为 movpn-09-01-server.conf 。对于辅助办公室中的OpenVPN客户端,会创建一个名为 /CN=SecondaryOffice 的特殊证书。因此,相应的CCD文件名为 /etc/openvpn/movpn/clients/SecondaryOffice 。其内容如下:

对于所有客户端,可以使用 basic-udp-client.confbasic-upp-client.ovpn 配置文件。顺便说一句,这显示了OpenVPN配置文件的灵活性。在大多数情况下,即使修改了服务器端的网络布局,或者将辅助网络引入VPN,也不需要更改客户端配置文件。

接下来,我们启动OpenVPN服务器和辅助办公室客户端,并确保CCD文件已被拾取。辅助办公室的VPN客户端可以在其VPN IP地址上 ping OpenVPN服务器,家里的测试用户也可以。

注:此时,VPN正在工作,但路由不起作用。

从中间开始,努力向外

解决此设置问题的最有效方法是将VPN链接视为中间,然后逐步向外工作,直到网络的所有部分都连接起来。首先,在二级办公室的OpenVPN客户端上要执行一些测试。对于几乎所有的测试,一个简单的 ping 命令就足够了。

请注意,如果第一个测试失败,则继续进行第二个测试是没有意义的,同样,如果第二个检测尚未工作,则继续第三个测试也是没有意义的:

在确保客户端可以访问服务器端局域网上的所有机器之后,是时候确保反过来也是正确的了。确保OpenVPN服务器可以访问辅助客户端后面局域网上的所有机器。要进行的测试非常相似:

此时,二级办公室的OpenVPN客户端应该能够访问服务器端局域网中的所有机器,而主办公室的OpenVPP服务器应该能够访问客户端局域网中的全部机器。只有一个步骤:确保服务器端局域网上的服务器可以连接到客户端局域网上的服务,反之亦然。同样,有四个测试要执行,从服务器端局域网上的机器开始:

【略】

通过有条不紊地完成所有这些步骤,我们可以解决几乎所有的路由问题。在某些情况下,可能需要更高级的调试技术。这可能需要我们暂时禁用防火墙规则,因此在尝试之前应该特别小心。

找个时间暂时禁用防火墙

OpenVPN邮件列表中有太多人无法使用路由的情况,事实证明这是一个过于严格的防火墙或iptables规则。无需禁用所有防火墙规则,但如果您在前面列出的十二个步骤中遇到困难,请尝试禁用与您无法访问或正在发送流量的设备相关的防火墙。

注:如果您需要使用NATted设置,请确保您没有禁用NATting规则。

如果其他方法都失败了,请使用tcpdump

低级网络工具 tcpdump 是测试连接性的好工具。为了调试路由问题,我们可以使用 tcpdump 查看是否有任何流量到达或离开特定的网络接口,我们可以检查此流量的源地址和目标地址。在Windows客户端或服务器上,运行Wireshark可能更容易(http://www.wireshark.org),其提供类似的功能,包括GUI。

在前面列出的十二个步骤中,以下 tcpdump 语句可以提供帮助:

1、在服务器上运行 tcpdump -nnel -i tun0 ,查看是否有任何流量通过VPN进入。

2、在服务器上运行 tcpdump-nnel-i eth0 (其中 eth0 是正在使用的服务器的LAN接口),查看LAN接口上是否有任何流量。如果没有,那么很可能防火墙规则正在丢弃隧道接口上的入站流量。

3、在服务器上运行 tcpdump-nnel-i eth0 ,查看是否有任何流量通过以下方式离开LAN接口:

此外,检查我们是否可以看到源地址和目标地址颠倒的服务器端网关的返回流量。

4、再次,在服务器上运行 tcpdump -nnel -i eth0,查看是否有任何流量使用以下数据包头离开LAN接口:

这里,172.31.1.XXX 是我们试图在服务器端局域网上访问的机器的IP地址。看到回程车辆了吗?

接下来的步骤,以此类推!

如何使用ping和iperf优化性能

从OpenVPN设置中获得最大性能可能很难实现。在干净的以太网网络上,OpenVPN的默认设置相当不错。然而,在千兆速度的网络上需要进行一些调整。

当使用ADSL或电缆调制解调器连接时,性能通常也很好。然而,在某些情况下,我们的OpenVPN隧道的性能可能远远落后于正常网络的性能。这些情况几乎总是依赖于ISP,但无论如何,探索如何提高性能是值得的。

优化性能的关键是首先要有良好的工具来衡量性能。测量网络性能的两个基本但非常宝贵的工具是 pingiperfiperf 工具在Linux、FreeBSD和Mac OS上很容易获得。有适用于Windows甚至Android的端口。

使用ping

使用 ping ,我们可以确定网络的最佳MTU大小。大多数网络运营商现在为客户提供1500字节的以太网式MTU。这导致1472字节的有效数据包有效载荷。剩下的28个字节是源地址和目标地址等TCP/IP开销。

但是,如果客户端和服务器之间的网络具有较低的MTU,那么它可以大大提高性能,将OpenVPN数据包的大小减小到略低于该大小。要了解我们网络的最大传输大小,我们使用以下方法:

在Windows上,我们使用以下内容:

这将向我们选择的远程服务器发送ICMP数据包,并设置 do not fragment 标志,指示网络路由器不要将此数据包分解为更小的比特。如果客户端和服务器之间存在MTU较小的网络,则 ping 命令将失败:

这告诉我们,如果我们使用1480的 fragment 大小或1480字节的MTU大小而不是默认值 1500 ,那么性能很可能会提高。请注意,这并不能保证——只有通过测量实际的VPN性能,我们才能知道实际的影响是什么。

使用iperf

通过使用 iperf ,我们可以测量VPN隧道内外的网络性能。这将让我们深入了解使用VPN隧道浪费了多少带宽。

在测量VPN隧道本身的性能之前,请务必尝试测量正常网络的性能。很难使VPN的性能优于底层网络。

首先,使用以下命令在服务器上启动 iperf

接下来,使用以下命令在客户端上启动 iperf

在用于测试的电缆网络上,结果如下:

【略】

这实际上是所用电缆连接的上传速度。我们现在可以在同一网络上测试VPN隧道的性能:

重复测量得到的数字非常相似,因此可以公平地说,VPN隧道的性能比底层网络低几个百分点。这实际上是有道理的,因为使用VPN确实会为原始数据的封装、加密和身份验证(签名)带来一些开销。很难进一步优化这个网络。

同样,对于所使用的电缆连接的下载速度,我们发现VPN隧道的性能要低几个百分点:

底层网络的性能如下:

现在,将其与VPN隧道进行比较:

我们再次看到性能下降了4.5%。

我们现在可以使用fragment和mssfix参数来查看是否可以提高性能。为了找到特定设置的最佳点,将进行一些试错工作。目前尚不清楚确切的最佳点是什么,但找到它的方法总是一样的。现在,将选项添加到客户端和服务器配置文件中:

通过这样做并改变 x ,我们得到以下结果:

X (bytes)Download (Mbps)Upload (Mbps)
120037.93.94
130038.14.01
140038.44.04
147238.84.06
150037.63.98
<none>39.04.09

我们可以得出结论,OpenVPN的默认设置实际上是这个网络的最佳选择。我们可以通过改变 tun-mtu 参数来重复这个练习,但我们会发现相同的结果。然而,建议首先使用 fragment 参数来调整性能,因为该参数对数据包的转发影响较小。

千兆网络

我们现在将在未使用的千兆以太网上执行相同的过程。底层网络的 iperf 性能上下为950 Mbps。

当我们使用 basic-udp-server.conf 配置启动OpenVPN服务器,并使用 basic.udp-client.conf 配置文件将客户端连接到该服务器时,我们实现了以下 iperf 性能:

现在表现明显下降。不幸的是,降低 fragment 参数在这里对我们没有帮助。使用 fragment 1200 ,我们分别实现了149 Mbps和115 Mbps。

在高速网络上,尝试加密密码也是有意义的。由于CPU上存在AES-NI扩展(分别为2 GHz Xeon E5 2620和3.5 GHz(turbo)Xeon E5 2643),本例中使用的服务器都能够执行快速AES指令。让我们添加以下内容:

我们现在得到以下结果:

在功能强大的CPU上,密码对性能有很大的影响。由于OpenVPN是一个单片程序,大量的内核根本没有帮助。CPU的时钟速度是一个主要因素。通过将3.8 GHz(涡轮增压)Core i7笔记本电脑连接到3.5 GHz Xeon E5-2643服务器,我们使用完全相同的配置实现了更高的吞吐量:

因此,如果你想在高速网络上设置OpenVPN隧道,那么最好的建议是使用支持AES-NI指令集的高时钟速度CPU。通过这样的设置,可以在两个方向上实现超过500 Mbps的网络速度。

使用tcpdump分析OpenVPN流量

低级网络工具 tcpdump 或其GUI等效工具Wireshark是解决网络问题和网络性能的最后手段。在本节中,我们将介绍捕获和分析OpenVPN产生的加密网络流量的过程。

首先,我们使用 basic-udp 配置文件设置我们的标准OpenVPN网络。在客户端上,还有一个web服务器正在运行。我们将在服务器端使用 wget 命令从web服务器检索文件,以便查看由此产生的网络流量。

我们在以太网接口上运行 tcpdump,并在隧道外执行 wget 时捕获网络流量:

tcpdump 输出结果如下(为清楚起见进行了修改):

【略】

正如我们所看到的,传输一个5KB的文本文件需要13个数据包。这些数据包中的大多数用于建立和断开连接,但有四个大数据包用于实际传输数据。四个数据包中的前三个数据包的大小为1514字节,这是以太网数据包的最大大小。

接下来,我们在隧道内运行相同的 wget 命令。我们现在观察以太网适配器上的加密流量:

【略】

在这里,我们看到22个数据包被捕获。前两个和后两个数据包是OpenVPN heartbeat 数据包,可以忽略。其余18个数据包是第一个 tcpdump 输出中所示数据包的加密等效数据包。正如我们在这里看到的,数据包的长度稍小,尤其是每个数据包的 payload 要小得多:最大的UDP payload 数据包是1445字节。这1445个字节包含来自 wget 命令的加密和签名数据。在我们的设置中,我们没有指定 fragment 参数,这意味着OpenVPN 2.3将默认为1450字节的内部片段。

每个数据包的总大小永远不会超过1487字节,这相当接近最佳值:通常,数据包不应超过MTU大小,即1500字节。

这个 tcpdump 屏幕转储还显示,除了OpenVPN之外,没有发生碎片。这很好,因为我们希望避免操作系统或网络造成的数据包碎片,以获得最佳性能。如果我们在这里看到了数据包碎片,那么这将是一个很好的迹象,表明我们需要在OpenVPN配置中添加额外的碎片。

让我们来看看如果我们将 fragment 1400 添加到我们的设置中会发生什么。我们重新启动服务器和客户端,然后重新运行 wget 命令。

在我们的设置中添加了 fragment 1400 后,我们可以在 tcpdump 输出中看到,数据包的有效载荷现在是1397字节,非常接近1400的限制。我们还可以看到,现在需要更多的数据包才能通过隧道传输5KB的文本文件,这意味着性能下降。从这个屏幕截图中,我们可以得出结论,我们应该再次删除该参数。

从前面的屏幕截图和前面的截图中,我们还可以推断出每个OpenVPN数据包都会产生42字节的开销。这种开销在一定程度上导致了使用任何VPN解决方案所产生的开销。它确实包含了整个开销,因为所有网络数据包都需要包含有关源地址、目的地址、数据包类型、校验和、标志等的开销信息。

最后,让我们来看看实际加密的OpenVPN数据包的内容。为此,使用Wireshark工具很方便(http://www.wireshark.org). Wireshark基本上在低级 tcpdump 工具之上提供了一个GUI。它可以解码大多数类型的网络流量的内容。

输出结果告诉我们以下内容:

此数据包将由OpenVPN接收,检查身份验证,解密和解压缩(如果我们指定的话)。然后将得到的未加密数据包转发到操作系统的路由表,路由表决定将数据包路由到哪里。在我们的例子中,数据包将保留在服务器上,并将被提供给 wget 进程。

总结

在本章中,您学习了一些排除和调整OpenVPN的基本技术。您还了解了如何读取客户端和服务器日志文件。你学会了如何发现和修复一些最常犯的错误。OpenVPN电子邮件列表中的大多数问题都是关于路由问题的,因此我们讨论了检测和修复路由问题。最后,工作设置和良好工作设置之间存在很大差异,因此我们查看了如何检测和解决性能问题的示例。

当然,OpenVPN并不完美,因此您的非工作设置也可能是由OpenVPN本身的错误引起的。有几种报告错误的渠道,包括电子邮件列表(openvpn-users@lists.sourceforge.net),一个IRC频道(freenode.net IRC上的 #openvpn )和一个论坛网站(https://forums.openvpn.net). 您还可以向这些频道报告功能请求或愿望列表,其中一些可能会成为OpenVPN的未来版本。

在下一章中,您将了解即将发布的OpenVPN版本中的新功能。您还将了解OpenVPN代码库目前已知的问题,以及解决这些问题的计划。