FreeS/WAN 简介,第二部分

作者:Mick Bauer

上个月我介绍了 FreeS/WAN,Linux 中用于安全虚拟专用网络 (VPN) 的 IPSec 隧道协议的实现。对于我的示例配置,我使用了常见的远程访问 (RA) VPN 场景。您可能还记得,当每个远程用户预计使用单独的连接连接到家庭网络时,会使用 RA VPN,从而形成每个用户一个隧道的设置。

但是,当您的部分或全部远程用户连接到同一个局域网 (LAN) 时会发生什么?我上个月提到了这种站点到站点 VPN 场景,但我没有解释如何设置一个。因此,使用 FreeS/WAN 构建站点到站点 VPN 是我们本月关注的重点。

架构:站点到站点 VPN

在我们深入研究 FreeS/WAN 配置之前,让我们快速了解一下架构方面的考虑。图 1 显示了典型的站点到站点 VPN 网络布局。

An Introduction to FreeS/WAN, Part II

图 1. 简单的站点到站点 VPN 设计

在图 1 中,每个站点的防火墙都充当隧道端点。有几个很好的理由使用防火墙作为 VPN 端点

  1. 便利性:大多数防火墙平台都支持 IPSec 或其他 VPN 协议,从而消除了配置和管理单独的 VPN 服务器所需的费用和时间。

  2. 安全性:充当 VPN 端点的防火墙可以以出色的粒度和准确性来管理进出 VPN 隧道的流量。

  3. 简易性:如果您的防火墙和 IPSec 软件设计为在同一主机上一起运行,那么使您的隧道正常工作并在出现问题时进行故障排除可能会容易得多。

但是,出于以下几个原因,这种类型的设置可能不可行或不可取

  1. 非互操作性:如果您无法控制 VPN 隧道的两侧(例如,如果您连接到供应商或合作伙伴的网络),则远程防火墙的 VPN 实现可能与您的防火墙不兼容。

  2. 性能:如果您的防火墙已经完全或过度订阅以执行其正常职责,则它可能无法支持 VPN 身份验证和加密的额外开销。

如果由于这些或其他原因,您无法使用防火墙作为 VPN 端点,则您可能更喜欢使用如图 2 所示的架构。
An Introduction to FreeS/WAN, Part II

图 2. 替代的站点到站点 VPN 设计

在图 2 中,每个 VPN 端点都是一台专用计算机(在图 2 中,两个端点都以这种方式设置,但您也可以混合搭配,例如,一端是组合的防火墙/VPN 端点,另一端是分离的端点)。将任何设备与防火墙并行放置似乎很鲁莽。这样的设备可以用作后门吗?

的确,它可以——除非 VPN 服务器经过仔细配置以接受 VPN 流量,并且其 VPN 软件经过仔细配置以仅接受来自批准的端点的 VPN 连接,即使用强大的身份验证机制。

让我们直接进入 FreeS/WAN,看看如何设置站点到站点 VPN,使其端点足够安全,可以驻留在防火墙或独立主机上。

示例场景

图 3 显示了一个站点到站点 VPN 场景,该场景在功能上等同于图 1 中的场景。也就是说,它在每个站点也具有相同的主机,充当组合的 Linux 防火墙和 FreeS/WAN IPSec 服务器。但是,图 3 提供了更多细节。首先,您可以看到每个网络都通过本地路由器连接到 Internet。其次,图 3 显示了隧道定义所需的 IP 地址(我们稍后会看到哪些 IP 地址在哪里使用)。

An Introduction to FreeS/WAN, Part II

图 3. 我们的示例站点到站点 VPN 场景

在此场景中,我们需要在两个站点的防火墙各自的“外部”接口之间建立 VPN 隧道。当一个站点 LAN 上的用户希望与另一个 LAN 上的主机通信时,防火墙会将这些数据包通过隧道发送。回复数据包采用相同的路径通过隧道返回。任一侧的主机都可以通过隧道发起连接。

防火墙限制了哪种类型的数据可以从任一侧进入和离开隧道。在组合的 iptables/FreeS/WAN 服务器上,即使涉及到网络地址转换 (NAT),这些防火墙规则也可以相同,就像没有使用隧道一样。本文稍后会对此进行解释。

应注意关于此场景的几个重要前提。首先,两个防火墙都运行 Linux 内核版本 2.4.18。其次,两个防火墙的内核都已使用 FreeS/WAN 版本 1.97 进行了修补,并且也安装了用户空间 FreeS/WAN 工具(相同版本)。第三,两个网络可以在没有 IPSec 的情况下相互访问,即以明文形式。(我们不希望它们以这种方式通信,但我们需要知道它们可以;否则,VPN 问题的故障排除会困难得多。)

交换主机密钥

此场景的另一项基本规则是使用 RSA 身份验证而不是“共享密钥”。虽然我不想完全重新解释上个月关于主机密钥生成和维护的资料,但回顾最重要的几点很重要。

您可能还记得,每个运行 FreeS/WAN 的主机都应该有一个唯一的主机密钥;您应该使用您安装的 FreeS/WAN 二进制软件包提供的默认密钥。但是,一旦您在给定主机上生成了新密钥,您就可以将该密钥用于该主机需要的任意数量的不同隧道。只要主机密钥的秘密部分(存储在 /etc/ipsec.secrets 中)保持隐藏,或者直到密码分析的进步使您的主机密钥过短,该密钥就仍然有用。(实际上,在 FreeS/WAN 本身由于某种原因变得过时之前发生这种情况的可能性非常渺茫。)

要使用 FreeS/WAN 1.92 或更高版本生成新的主机密钥,请输入此命令

# ipsec newhostkey --hostname my.host.fqdn \
--output /etc/ipsec.secrets --bits 2192

这会生成一个 2192 位 RSA 密钥,并将其公钥和私钥组件都保存在 /etc/ipsec.secrets 中。我上个月没有指出,由于这些命令处理 RSA 密钥,因此比方说像 3DES 这样的分组密码需要更长的密钥长度。

因此,不要试图使用 128、196 或其他三位数的值作为 newhostkey --bits。RSA 和 DSA 等公钥机制的工作方式不同,它们的密钥长度必须大约是分组密码和流密码密钥长度的十倍。1,096 位是您应该考虑的最小 RSA 密钥大小;2,192 位更安全。

要以可以直接复制并粘贴到隧道定义中的格式显示您的新公钥,请使用此命令

bash-# ipsec showhostkey --left

如果您想打印 rightrsasigkey 语句而不是 leftrsakey 语句,可以使用选项 --right。

请记住,此命令的输出可以安全共享。它仅包含您主机签名密钥的公共组件。您可以不加密地通过电子邮件发送它,将其发布在网站上,或者将其设置为音乐并在您最喜欢的咖啡店演唱它。这就是为什么 RSA 身份验证比共享密钥身份验证更方便的原因,在共享密钥身份验证中,每当您希望构建 IPSec 隧道时,您必须安全且隐蔽地将身份验证凭据(共享密钥字符串)发送到另一个站点。RSA 身份验证允许您马虎(除了 /etc/ipsec.secrets,它必须始终保持仅 root 可读);共享密钥身份验证则不允许。

设置 ipsec.conf

FreeS/WAN 的主要配置文件,除了 /etc/ipsec.secrets 之外,是 /etc/ipsec.conf。为了简化事情,FreeS/WAN 的设计方式使得隧道定义在 FreeS/WAN 隧道的两个端点上通常看起来相同。因此,以下大多数示例行在我们的示例场景中的两个防火墙上都是相同的。

上个月我主要关注隧道定义。我们也会在这里介绍它们。但首先,让我们更深入地研究 config setup 和 conn %default 部分。列表 1 显示了我们的防火墙之一的 config setup(哪个防火墙都无关紧要)。

列表 1. /etc/ipsec.conf 中的基本设置

列表 1 中的第一个参数 interfaces 至关重要。它定义了主机将侦听来自其他 IPSec 服务器的 IPSec 连接的接口。这不应与主机侦听通过隧道发送的数据包的接口混淆。如果您将 Internet(或其他不受信任的网络)视为外部,将本地 LAN 视为内部,请始终确保 interfaces 参数设置为您的外部接口。

klipsdebug 和 plutodebug 这两个调试选项确定了 FreeS/WAN 的内核接口守护进程 (KLIPS) 和 IKE 密钥守护进程 (Pluto) 执行的日志记录量。这两个参数都接受不言自明的魔术值 all 和 none,以及可以记录的各种特定 IPSec 属性/事件。有关这些的完整列表,请参阅 ipsec_klipsdebug(8) 和 ipse_pluto(8) 手册页。

参数 plutoload 指定在 FreeS/WAN 启动时要初始化哪些隧道定义。魔术值 %search 告诉 Pluto 检查每个后续隧道定义的 auto 参数以确定这一点(即,auto 设置为 add 的每个隧道)。

类似地,值 plutostart 告诉 Pluto 在 FreeS/WAN 启动时尝试自动连接到哪些隧道。换句话说,plutoload 只是告诉 Pluto 允许其他主机启动指定的隧道,而 plutostart 则告诉 Pluto 自己启动指定的隧道,而无需等待其其他端点。同样,可以指定 %search 值。在这种情况下,它将匹配 auto 设置为 start 的隧道定义。

列表 2. /etc/ipsec.conf 中的隧道默认值

列表 2 显示了 ipsec.conf 文件中后续的 conn %default 部分。列表 2 中的第一个参数 keyingtries 设置为零,实际上转换为无限制。这意味着当 Pluto 尝试启动或替换隧道时,它会尝试根据需要多次对其进行密钥交换。对于站点到站点 VPN 来说,这是一个合理的设置,其中两个主机都具有持久的网络连接,但它不适用于远程访问 VPN,其中远程客户端将仅零星地在线。

disablearrivalcheck,如果设置为 no,则会导致 KLIPS 确保从 IPSec 隧道进入主机的每个数据包在其标头中都具有合理的源 IP 和目标 IP 地址。默认值为 yes,它会阻止这些检查,但您应该将其设置为 no,除非您真的知道自己在做什么。

最后,authby 允许您为隧道选择默认身份验证方法,正如我之前所说,对于我们的示例场景,这将通过 RSA (rsasig) 进行。现在我们来看实际的隧道定义——它显示在列表 3 中。

列表 3. /etc/ipsec.conf 中的隧道定义

因为这是一个站点到站点场景,所以 FreeS/WAN 的服务器 = 左,远程访问客户端 = 右的约定没有意义。因此,哪一侧被指定为右或左是完全任意的。重要的是在两个主机的设置中的隧道定义中保持一致。在这里,Internet 左侧的站点(图 3)是左侧,而 Internet 右侧的站点是右侧。这听起来很明显,但如果我决定将右侧设为左侧,反之亦然,隧道行为将相同(前提是我在两侧都使用了相同的配置)。

如您所见,在列表 3 中,left 设置为外部(Internet 可访问,隧道侦听)接口的 IP 地址。但是,leftsubnet 设置为接收传入数据包的网络地址(即,离开隧道)。

leftnexthop 是防火墙/IPSec 主机和 Internet 之间的下一跳的 IP 地址。leftrsasigkey 显然是左侧主机的主机密钥。可以通过运行命令 ipsec showhostkey --left 来获得此行(以及上面的注释)的原文。

右侧参数相同,但适用于右侧。我留给您使用您的演绎能力来弄清楚这些参数对应于图 3 中的哪些主机。

最后,我们有隧道的 auto 参数,它设置为 start。当 Pluto 守护进程执行其搜索以查找有关在启动时如何处理隧道定义的指令时(如列表 1 之后的章节中所述),此设置告诉它启动上面定义的隧道。

正如我一直在暗示的那样,在此示例场景中,两个防火墙和网关的 /etc/ipsec.conf 文件是相同的。一旦设置好它们,我们就可以在每个主机上启动 IPSec 并开始隧道传输。在大多数发行版上执行此操作的命令是

bash-# /etc/init.d/ipsec start

如果 IPSec 已经在运行,请使用

bash-# /etc/init.d/ipsec restart
一旦在两个主机上(重新)启动 IPSec,隧道将建立,并且每个网关将开始通过隧道路由寻址到另一个网络的流量。此路由是自动完成的,基于您在 /etc/ipsec.conf 中的隧道定义中定义的 leftsubnet 和 rightsubnet 参数。
防火墙和 NAT

自然地,您会希望限制来自另一个网络的主机可以在您的网络上执行哪些操作,反之亦然。我之前说过,在运行 FreeS/WAN 的 Linux 主机上的防火墙规则与没有隧道时不必有任何不同。即使使用 NAT,这仍然成立。在每个网关上编写防火墙规则时,设置 FORWARD、POSTROUTING 和 PREROUTING 规则,就像您没有使用 IPSec 一样——只需注意接口。如果您使用 -i 和 -o 参数,如果您指的是“ipsec0”(或者如果您指的是“所有隧道接口”,则为“ipsec+”),请不要说“eth0”。如有疑问,请尝试在防火墙规则中坚持使用 IP 地址而不是接口名称。

此外,确保不对隧道数据包执行 NAT。IPSec 数据包的标头在每个数据包的数据字段的主体中进行校验和。重写 IP 标头(例如,通过转换源 IP 或目标 IP)会违反此消息摘要,并且会发生奇怪的事情。您可以对离开隧道或在数据包进入隧道之前的数据包执行 NAT,但不能在它们正在处理时执行 NAT。

无论您做什么,您都至少需要在每个网关上添加三个新规则,以允许 IPSec 密钥协商和隧道传输。在 INPUT 和 OUTPUT 链中,您需要允许发送到 UDP 端口 500 的数据包、IP 协议 50 数据包和 IP 协议 51 数据包。两个网关上的相关规则将类似于列表 4 中所示的内容。

列表 4. 允许 IPSec 的 iptables 规则

结论

有了这些,您就可以安全且廉价地将您的网络连接到您的供应商、合作伙伴和熟人的网络。祝你好运!

资源

Mick Bauer (mick@visi.com) 是明尼苏达州明尼阿波利斯市 Upstream Solutions, Inc. 的网络安全顾问。他是即将出版的 O'Reilly 图书《Building Secure Servers with Linux》的作者,“Network Engineering Polka”的作曲家以及一位自豪的父母(孩子的父母)。

加载 Disqus 评论