第五章:tun模式下的高级部署场景

VPN的基本配置相对简单,但将VPN与网络的其他部分集成是一项更困难的任务。在本章中,我们将探讨OpenVPN的一些高级部署场景,这超出了VPN的基本安装和配置。其中一些场景基于OpenVPN邮件列表、论坛和IRC频道上用户的实际问题。我们将涵盖以下主题:

本章中给出的示例依赖于上一章第4章“带tun设备的客户端/服务器模式”中的示例。最值得注意的是,将使用基本生产级配置文件和添加额外的安全部分。

本章以Windows7为例,有大量截图,略

通过VPN启用文件共享

正如前一章的”路由和服务器端路由“部分所述,只有当VPN客户端可以访问服务器端资源时,VPN才真正有用。为了访问这些服务器端资源,需要路由。这确保了服务器端局域网和VPN之间的网络流量正常流动。

设置VPN最常见的用例之一是允许远程工作人员访问公司网络上的资源。公司网络中的文件通常存储在基于Windows的文件服务器上。为了使用网络名称浏览Windows文件共享,需要一个WINS服务器。

同样,这里描述了访问服务器端网络上资源的一种非常常见的布局:

Client端tun0地址为10.200.0.2。

Server端tun0地址为10.200.0.1,LAN地址为192.168.122.10;在Server端网络上有文件和WINS服务器,其地址为192.168.122.1。

我们以 basic-udp-server.conf 文件为基础,加入三行:

将此文件保存为 movpn-05-01-server.conf

新加的第一行将服务器端LAN添加到需要通过VPN路由的网络集合中。

第二行通过VPN隧道重定向所有网络流量。需要此行来确保OpenVPN和TAP-Win适配器被视为私有。文件共享只能使用专用网络适配器(与公共网络适配器相反)。

最后一行指示OpenVPN服务器向OpenVPN客户端推送额外的DHCP选项,其中包含WINS服务器的IP地址。

我们使用此配置文件启动OpenVPN服务器。我们再次使用64位Windows7 Pro机器作为OpenVPN客户端,其中安装了OpenVPN 2.3.5-l001的X86_84版本。

启动OpenVPN GUI应用程序,选择配置 basic-udp-client然后点击Connect

就像我们在上一章的 路由和服务器端路由 部分示例中所做的那样,我们确保OpenVPN服务器正在转发IP流量,并在服务器端网关上添加额外的路由,以允许VPN流量通过VPN服务器正确路由回来。

建立VPN连接后,我们转到Network and Sharing Center,验证TAP适配器(在下面的屏幕截图中名为 vpn0)是否标记为non-public,以及它是否是HomeWork 网络/组/位置/的一部分。如果TAP适配器被标记为public,这意味着Windows不信任来自此适配器的流量,它将拒绝通过VPN共享文件。在本章的Windows network locations – public versus private部分,我们将深入探讨此主题的细节。

正如我们所看到的,OpenVPN连接vpn0Work网络的一部分,这意味着允许文件共享。

测试文件共享是否正常工作的第一种方法是使用其IP地址浏览到文件服务器。您可以通过打开命令提示符窗口并键入以下行来完成此操作:

此时,将弹出一个身份验证对话框。

输入文件服务器的凭据。现在,将打开一个包含远程共享内容的Windows资源管理器窗口。

使用NetBIOS 名称

使用文件服务器的Windows网络名称比通过IP地址浏览文件共享要方便得多。为此,Windows客户端需要一个WINS服务器地址。行 push “dhcp-option WINS 192.168.122.1” 将此WINS地址推送到所有连接的OpenVPN客户端。建立VPN连接后,我们可以通过在命令shell中发出 ipconfig /all 命令来验证是否使用了正确的WINS服务器。

WINS服务器的IP地址列在Primary WINS Server行上,这表示Windows将使用此服务器解析WINS名称。

现在,当打开Network and Sharing Center时,文件服务器将显示其NetBIOS名称(FILESERVER)。

当我们点击此图标时,我们将看到文件服务器上的可用共享。

当我们再次点击共享时,会弹出一个身份验证对话框。输入文件服务器的凭据。将打开一个包含远程共享内容的Windows资源管理器窗口,就像使用IP地址时一样。

使用nbtstat解决连接问题

在解决Windows文件共享问题时,Windows命令行工具nbtstat非常有价值。您可以查找Windows NetBIOS名称并查看可用共享,也可以找到与特定IP地址对应的NetBIOS名称。

使用LDAP作为后端身份验证机制

通常,VPN的安全性基于X.509证书/私钥对,VPN的所有用户都必须拥有该对证书才能访问。通过要求用户在连接到OpenVPN服务器时也提供用户名和密码,可以进一步提高VPN的安全性。

在服务器端,可以使用多种机制来验证用户名和密码:

还可以对Windows Active Directory域进行身份验证,因为这与使用独立的LDAP服务器非常相似。在这个例子中,我们将向您展示如何根据LDAP服务器对用户进行身份验证。

支持LDAP后端身份验证的最简单方法是使用 openvpn-plugin-ldap 模块。在大多数Linux发行版上,此模块需要单独安装。例如,在基于RPM的系统上,您可以使用以下命令:

我们从 basic-udp-server.conf 文件开始,添加一行:

将以上文件保存为 movpn-05-02-server.conf 然后创建 movpn_ldap.conf 文件:

这是一个非常基本的 authldap 配置文件,使用URI处的安全LDAP服务器 ldaps://ldap.example.org ,端口 636 ,以及基于用户ID( uid=%u )和LDAP属性 authorizedService=login 的LDAP搜索过滤器。URI表示通过 ldaps:// 服务与服务器的SSL连接。这些设置高度依赖于所使用的LDAP服务器,但 openvpn-ldap-auth 插件几乎可以适应任何配置。例如,在此设置中,不使用绑定连接到LDAP服务器。但是,可以添加此选项以及其他连接选项。

接下来,我们在客户端配置 basic-udp-client.ovpn 中添加一行:

将其另存为 movpn-05-02-client.ovpn 并启动客户端。客户端首先使用其X.509证书和私钥文件启动与服务器的连接,然后提示用户输入用户名和密码。

如果输入了正确的凭据,则建立连接。否则,服务器将拒绝访问。

除了使用 openvpn-ldap-auth 插件,我们还可以使用PAM插件。然后,OpenVPN将查询PAM子系统进行身份验证。如果PAM子系统被正确配置为根据LDAP数据库对用户进行身份验证,那么将实现相同的功能。OpenVPN服务器配置文件看起来像这样:

LDAP后台身份验证故障排除

LDAP后端身份验证插件的故障排除可能很棘手。首先要做的最重要的事情是确保VPN服务器能够连接到LDAP服务器,并且可以检索用户信息。为此, ldapsearch 工具非常方便。此工具包含在OpenLDAP客户端实用程序包中。

使用 movpn_ldap.conf 文件中的 BaseDNSearchFilter ,我们可以查询LDAP服务器:

-x 选项表示与服务器的匿名(未经身份验证)绑定,-H 选项表示服务器URI。请注意,URI与主机名不同,因为它将包括协议(SSL或纯文本)以及主机名。ldapsearch 的输出应该是这样的:

在尝试连接OpenVPN客户端之前,请确保此功能正常工作。如果这有效,但客户端无法连接到OpenVPN服务器,则增加服务器上的详细信息并注意LDAP消息。将以下行添加到配置文件的底部并重新启动服务器:

重新连接客户端并查看服务器日志中的任何LDAP身份验证消息。对于失败的连接尝试,服务器日志将包含以下行:

在这些日志消息中,连接特定的详细信息,如客户端IP地址和UDP端口号,被替换为[…]。

过滤OpenVPN

就像系统或服务器上的任何其他接口一样,可以使用适用于操作系统的防火墙软件过滤tun和tap适配器接口。在许多情况下,出于路由和过滤的目的,最好将OpenVPN服务器逻辑地放置在网络中心位置,例如在边界路由器处或附近。对于家庭来说,这可能是电缆或DSL调制解调器。在企业网络上,这通常是一个实际的核心路由器,如思科或瞻博网络边缘设备。

根据平台和您自己或企业的偏好,防火墙可以是OpenVPN服务器和未受保护的互联网之间的单独设备,也可以是与OpenVPN服务器在同一系统上运行的软件。较大的安装甚至可能有多个防火墙。

对于我们的示例,我们将只允许从VPN客户端到网络其他部分的端口80和443。

FreeBSD 示例

在FreeBSD上,我们使用 pf 过滤通过VPN进出的流量。在FreeBSD上,OpenVPN接口是tun0。首先,在 rc.conf 中启动 pf

我们在默认的 /etc/pf.conf 中添加一条简单的规则:

然后启动 pf

使用 pfctl ,我们可以列出规则及其计数器:

此时,我们有一个简单的规则集,它简单地允许所有接口上的所有数据包。由于这不是一本关于掌握 pf 的书,我们不会深入了解整个配置的细节。这是一个示例过滤器,它允许所有接口上的所有流量,除了 tun0tun0 上的流量将被过滤入站,因此只能从VPN客户端连接到LAN的端口 80443 。将允许 tun0 上的出站流量。

OpenVPN和FreeBSD都有 pf 包过滤器。在上面的例子中,我们使用的是内核支持的 pf ,而不是OpenVPN内置的 pf

Windows 示例

假设您已经在Windows 7 Professional系统上运行了OpenVPN服务器,您将通过Control Panel访问防火墙配置。打开Control Panel后,在搜索框中键入 firewall,然后单击Windows Firewall。从窗口左侧面板上的可用选项中,单击Advanced Settings。这将显示防火墙配置实用程序。

点击Advanced settings打开Windows Firewall with Advanced Security程序。

进入实用程序后,我们需要创建两个入站规则。第一条规则将阻止来自VPN的所有流量,第二条规则将允许来自VPN的端口 80443 上的流量。

打开New Inbound Rule Wizard后,选择创建自定义规则的选项,如下图所示。这使我们能够识别有效所需的所有特定入站地址范围和端口。

在第二页上,选择All programs的单选按钮,将此规则应用于所有程序。

在第三个入站规则屏幕上,在入站规则上指定TCP端口 80443,并允许它们来自所有远程端口。

对于范围页面,指定本地VPN IP范围:

然后,通过选择Any IP address(这是默认设置)来允许所有远程IP地址。稍后,在创建块规则时,您将保留默认值——这两个值都适用于此页面上的All Ports

您也可以将此应用于VPN IP范围,只允许VPN主机地址联系VPN资源。省略此限制允许您可能希望路由的其他远程子网(例如使用 --iroute)。

接下来,从操作列表中选择Allow the connection。稍后,在创建阻止规则时,您需要在此页面上选择Block the connection

选中向导Profile页面上的所有三个框。这将允许规则运行,而不管分配的接口配置文件(Public, Private, 或 Domain)如何。我们稍后会讨论这个问题。

入站规则向导的最后一页允许您设置名称。选择一些描述性的内容,使管理员能够快速识别规则及其应用方式。在我们的例子中,我们将名称设置为 VPN - Allow 80,443作为允许规则。

现在创建了允许规则,再次执行这些步骤并创建您的阻止规则。此规则将阻止来自VPN的所有流量。结合我们已经创建的允许规则,它只允许我们的VPN客户端通过端口80443上的VPN连接。

在向导的每一页上为您的阻止规则使用以下设置:

保存后,您将在列表顶部看到一对VPN规则。

具有高级安全性的Windows防火墙是第一匹配防火墙类型。这意味着,一旦防火墙规则与给定的网络数据包匹配,规则集的处理就会停止,并应用该规则中的给定操作。Linux iptables数据包过滤器是另一个第一匹配过滤器。其他数据包过滤器,如OpenBSD的pf,是最后一个匹配,这意味着规则将继续处理到最后。

OpenVPN具有内置的过滤功能,但该代码多年来一直未被修改,需要额外的插件才能运行。开发人员认为该代码目前不可行,但该功能可能会在未来恢复。

在桌面版本的Windows上执行许多“服务器”类型的任务通常需要管理员稍微偏离常规。例如,Windows Server 2008具有比上述示例中使用的Windows 7 Professional更好的防火墙编辑工具。

基于策略的路由

基于策略的路由利用防火墙或其他数据包过滤器来路由流量,不仅基于源和目标IP地址,还基于源或目标端口。基于策略的路由的一个常见用途是通过VPN发送所有未受保护的端口80流量,但允许其他流量(如端口443上的SSL流量)通过普通互联网。

基于策略的路由是需要在源头上完成的事情。在大多数情况下,这意味着它将应用于OpenVPN客户端。在某些情况下,这可以在OpenVPN服务器上增强,但灵活性大大降低。

每个防火墙或数据包过滤软件都以不同的方式处理策略路由。我们无法将Windows 7防火墙配置为基于源端口或目标端口进行路由,甚至OpenBSD-pf数据包过滤器也有特定的注意事项。

Windows网络位置——公共与私有

OpenVPN邮件列表中反复出现的一个问题是如何将OpenVPN的TAP-Win虚拟网络适配器的网络位置从公共更改为私有。随着Windows Vista的推出,这个问题开始出现。不幸的是,这个问题的答案很长。在本节中,我们将探讨允许我们更改Windows客户端上TAP-Win适配器的网络位置的不同方法。

背景

从Windows Vista开始,微软引入了网络位置的概念。在Windows 7中,有三个网络位置:Home, Work, 和 Public。这些网络位置适用于所有网络适配器:有线网络适配器、无线适配器,以及OpenVPN的虚拟TAP-Win网络适配器。

Home 网络位置用于家庭网络,并提供高级别的信任。它还包括Home group功能,在该功能中,计算机可以轻松连接到家中的所有其他设备。同样,Work网络位置在工作中提供了高度的信任,允许计算机共享文件、连接到打印机等。在Windows 8中,HomeWork网络位置合并在一起成为Private网络位置。

Public网络位置不受信任,对入站和出站网络资源的访问受到Windows的严格限制,即使禁用了Windows防火墙。

启用Windows防火墙后,Private 防火墙配置文件将应用于HomeWork 网络位置中的所有网络适配器,Public 防火墙配置文件则应用于Public 网络位置中所有网络适配器。

要使网络适配器可信,它必须通告默认网关,或者网络适配器必须是Windows域的一部分。

当Windows无法确定网络的位置时,它会自动选择Public 网络位置。不幸的是,当网络适配器被分类为Public 时,无法更改状态。

使用重定向网关更改TAP-Win适配器位置

OpenVPN可以使用配置指令在远程TAP-Win适配器上设置默认网关:

通常,建议您将参数 def1 添加到此选项中。def1 选项导致OpenVPN不添加新的默认网关(在网络方面,路由0.0.0.0/0.0.0.0),而是添加两条具有网络掩码 128.0.0.0 的路由,如前一章所述。 def1 选项的缺点是Windows无法将TAP Win适配器识别为具有默认网关。有关 redirect-gateway 选项的不同替代方案的更多详细信息,请参阅第4章“带tun设备的客户端/服务器模式”。

为了测试此选项,我们在 basic-udp-server.conf 文件中添加一行:

现在,将其另存为 movpn-05-03-server.conf 。使用此配置文件启动OpenVPN服务器,并使用默认的 basic-udp-client.ovpn 配置连接Windows 7客户端。

这一次,在客户端成功连接后,Windows将询问将新网络放置在哪个位置

选择Work 网络,之后Windows将允许您为VPN网络选择自己的名称和图标。

我们选择了 VPN 名称,选择了其他图标,然后单击OK

TAP-Win适配器现在是受信任的,允许通过此网络以及其他受信任的协议共享Windows文件。

使用redirect-gateway的缺点之一是,VPN适配器现在是唯一具有默认网关的适配器,因此是可信的。连接到Wi-Fi网络 eduroam 的无线网络适配器现在缺少默认路由,突然间成为未知网络的一部分,不再受信任。这可以在以下Windows 7Network and Sharing Center的屏幕截图中看到。

当VPN连接停止或断开时,使用没有 def1redirect-gateway的最大缺点变得显而易见。由于Windows OpenVPN客户端上的默认网关已被替换,因此无法再可靠地恢复VPN启动前存在的默认网关,所有互联网连接都将丢失。在大多数情况下,需要重新启动(无线)本地网络连接才能恢复网关。

使用组策略编辑器强制适配器为私有

更改TAP Win适配器位置的第二种方法是使用Windows组策略编辑器。使用此工具,可以强制TAP Win适配器(或任何未标识的适配器)为privatepublic

  1. 打开Command prompt并启动Group Policy

  2. 选择Network List Manager策略,然后双击右侧窗格中的Unidentified Networks

  3. 将弹出一个新的Unidentified Networks Properties窗口。将Location Type设置为Private ,然后单击OK

  4. 在没有redirect-gateway标志的情况下重新启动OpenVPN客户端。

Windows现在将自动将适配器标记为Private ,并再次询问适配器应放置在哪个网络中:Home还是Work。但是,这次无法修改所选网络类型的图标和名称。

上述指令将所有未识别的网络设置为Private ,并可能预设其他负面的安全副作用。在设置之前,请确保您了解此更改的全部含义。

使用额外的网关更改TAP Win适配器位置

更改适配器位置的一种更优雅的方法是在服务器配置中添加一个额外的网关地址:

当OpenVPN客户端连接时,它将向系统路由表添加一个额外的默认路由。此路由将始终具有比常规默认网关更高的度量,但适配器现在是受信任的。

在Windows 7中,适配器的度量通常会自动计算为网关度量和接口度量的总和。接口指标基于适配器的类型和速度。由于OpenVPN的TAP-Win适配器注册为10 Mbps适配器,因此它总是比速度更高的有线或无线适配器具有更高的指标(也就是说,它不太可取)。

这些指标可以使用 netsh int ip show config 命令显示:

可以关闭自动度量计算并恢复到旧版本Windows的行为。为此,请转到网络适配器的TCP/IPv4 Properties选项的Advanced TCP/IP Properties对话框。

在这种情况下,TCP/IPv4 Properties窗口中指定的度量将确定系统中的默认路由。如果TAP-Win适配器的指标高于non-VPN适配器的指标,那么实际上所有流量都是通过VPN路由的!

这种方法的优点是,旧的默认网关保持不变,从而避免了VPN连接断开或停止时默认网关丢失的问题。

结合额外网关重定向所有流量

作为使用OpenVPN配置选项影响网络位置的最后一个例子,我们将添加一个额外的网关,并使用 def1 重定向默认网关:

将文件另存为 movpn-05-04-server.conf。使用此配置文件启动OpenVPN服务器,并使用默认的 basic-udp-client.ovpn 配置连接Windows 7客户端。

OpenVPN客户端重新连接后,IPv4路由表现在有以下条目:

第一条路由是原始网关。第二条路由是TAP-Win适配器的额外 0.0.0.0/0路由。这会导致Windows信任适配器。第三条和第四条路由由 redirect-gateway def1命令通过添加路由 0.0.0.0/1128.0.0.0 来设置。

OpenVPN提供了两条比默认的 0.0.0.0/0 路由更具体的新路由。TCP/IP路由指定应始终选择更具体的路由,而不管接口度量如何。因此,所有流量都会通过VPN隧道重定向。

Network & Sharing Center窗口现在将LAN网络和VPN网络都显示为受信任的。

这种方法的优点如下:

快速检查链接https://www.whatismyip.com将显示所有流量现在都通过VPN路由。另一种验证方法是在Windows命令shell中使用 tracert

在Mac OS X上,OpenVPN的Tunnelblick客户端能够在连接到VPN后检查外部IP是否已更改,然后在IP没有更改时通知用户。

traceroute 输出中的第一跳是VPN服务器地址,这证明系统的默认网关现在确实是VPN适配器。

使用带有HTTP或SOCKS代理的OpenVPN

OpenVPN支持通过HTTP或SOCKS代理进行操作,无需身份验证、基本身份验证和NTLM身份验证。我们将介绍HTTP和SOCKS代理服务器,包括有身份验证和没有身份验证的服务器。

HTTP 代理

HTTP代理需要使用TCP进行OpenVPN隧道传输。如果您当前正在使用UDP,则服务器和客户端配置中的协议参数都需要更新:

配置后,通过添加 --http-proxy 配置指令向客户端添加代理支持。例如,假设您的局域网需要一个匿名代理进行出站连接,并且该服务器位于默认端口 1080 上的 192.168.4.4 。您的配置如下:

这将允许您的OpenVPN客户端连接通过本地网络上的代理服务器连接到远程OpenVPN服务器。经过身份验证的HTTP代理没有太大区别,只需将前面命令中的 none 替换为身份验证信息:

前面的命令连接到与我们之前相同的代理服务器和端口,但查询用于HTTP基本身份验证的用户名和密码的标准输入。此外,支持身份验证的方法包括一个 auth 文件,它类似于核心的OpenVPN密码文件——只是两行中的明文用户名和密码:

在前面的示例中,传递 auth 文件路径和文件名来代替 stdin 关键字。设置 auto 允许OpenVPN确定从哪里查询凭据,包括通过管理控制台。

一些HTTP代理可能会根据传递的HTTP用户代理或其他HTTP选项限制访问或身份验证。这些可以使用几乎任何任意http选项的 http-proxy-option 配置参数来定义。常见的示例是用户代理字符串和HTTP版本字符串:

所有这些选项都可以在标准的OpenVPN客户端配置中或在运行时的命令行上定义。

如果你想让OpenVPN重试连接到摆动的HTTP代理,请指定 --http-proxy-retry 选项。这将导致OpenVPN模拟OpenVPN进程上的 SIGUSR1 重置,从而导致隧道重新连接。

SOCKS 代理

除了HTTP代理之外,OpenVPN还支持SOCKS代理。如果你想了解更多关于HTTP和SOCKS代理之间的差异,维基百科在http://en.wikipedia.org/wiki/SOCKS或者,您可以在以下网址查看特定于协议的Request For Comments (RFC——征求意见稿):

对于我们的示例,我们将再次假设代理服务器 192.168.4.4 位于默认端口 1080 上。但这一次,它将是一个SOCKS5代理。与HTTP代理示例不同,允许使用UDP或TCP与标准SOCKS5代理服务器进行隧道传输。然而,这需要注意。

在OpenVPN客户端配置中添加以下行,将其指向我们的示例代理服务器:

与其他身份验证文件一样,一个在单独的行中包含用户名和密码的纯文本文件就足够了:

与前面一样,stdin 可以代替 auth 文件的路径和文件名。此外,如果在与代理服务器的连接丢失或中断时需要重新连接/重试,请指定选项 --socks-proxy-retry ,以允许OpenVPN模仿 SIGUSR1 重新启动VPN。

您可以使用SSH协议创建一个SOCKS5本地服务器,并通过该隧道传输OpenVPN。这样做的一个限制是SSH SOCKS5代理只需要TCP连接。OpenVPN中的流量可以是TCP/UDP,但OpenVPN隧道本身必须是 --proto tcp

总结

在本章中,您学习了如何将OpenVPN集成到现有的网络和计算机基础设施中。这适用于服务器端。我们还了解了如何使用LDAP作为后端身份验证系统,以及如何使用基于策略的路由将OpenVPN提供的VPN无缝集成到常规网络中。在客户端,我们解决了将OpenVPN集成到Windows操作系统中的问题,以及无法直接联系OpenVPN服务器的情况。

当然,这些只是高级部署场景的几个示例,我们仅限于tun模式。这是有目的的,这样我们就可以证明tun模式适用于大多数OpenVPN部署。有些部署场景需要抽头模式甚至桥接,下一章将介绍这些场景。