FreeS/WAN 简介,第一部分
在过去的五年左右,IPSec 已经成为构建加密虚拟专用网络 (VPN) 连接的领先标准。FreeS/WAN (www.freeswan.org),即免费安全广域网,是最流行的也是最成熟的 IPSec 免费实现之一,它专门在 Linux 系统上运行。本月和下个月,我们将讨论为什么以及如何使用 FreeS/WAN 进行安全网络通信,首先从安全的无线网络开始。
直到最近,VPN 最常见的两种用途是网络到网络(站点到站点)连接和远程访问解决方案。在站点到站点连接(图 1)中,每个网络/站点都有一个 VPN 网关,这是一个 VPN 服务器,它通过 IPSec(或其他 VPN 协议)隧道与其他 VPN 网关通信。它还充当本地网络上需要向其他连接的 VPN 站点发送数据包的主机的路由器。换句话说,在站点到站点 VPN 中,多个用户或主机共享单个隧道以与远程网络上的多个主机通信。
远程访问 VPN,包括无线 LAN 上使用的那种,略有不同。远程访问 VPN 隧道不是将整个网络连接到其他网络,而是将单个用户或计算机连接到远程网络(图 2)。通常,用户的本地 VPN 网关只是一个在她本地系统上运行的软件应用程序(远程 VPN 网关通常是家庭网络上的防火墙或专用 VPN 设备)。
无线局域网 (LAN) VPN 是远程访问 VPN 的一个重要子类别。无线网络由于其便利性和低成本而越来越受欢迎。然而,根据定义,它们通过无线电波广播所有数据包,因此很容易被窃听。网络供应商曾试图通过创建同名的无线加密标准 (WEP) 来提供有线等效的隐私,但 WEP 的加密实现中的弱点使其过早地过时了。因此,许多使用无线 LAN 的组织都关闭了 WEP。相反,他们使用 VPN 隧道来加密无线链路。
回到图 2,请注意单个系统可以充当组合的 VPN/无线网关。图 3 显示了一个同样有效的拓扑结构:无线和 VPN 网关是独立的设备。
正如我之前所说,IPSec 是最流行的 VPN 协议。由于它是 IP 协议的扩展,因此它是 Internet 的“官方”VPN 协议。几乎在 IPSec 存在的时间里,John Gilmore 和 FreeS/WAN 项目团队一直在尽最大努力通过开发和免费提供 Linux 的 FreeS/WAN 软件包来促进 IPSec 的广泛采用。有关 FreeS/WAN 的权威信息和最新版本,请访问他们的主页 www.freeswan.org。可以肯定地说,FreeS/WAN 成熟、文档完善且支持良好。如果您运行 Linux,FreeS/WAN 是 最佳 的 VPN 需求选择。
与 Netfilter 类似,FreeS/WAN 由一个执行实际工作的内核模块和用于配置它的用户界面组成。与 Netfilter 不同,FreeS/WAN 未包含在标准 Linux 内核源代码中,因此不属于大多数 Linux 发行版的库存内核的一部分。这是由于许多国家的加密出口限制。
追溯修改甚至重新编译内核可能听起来是安装 FreeS/WAN 的一种笨拙方式。然而,许多 Linux 发行版,包括 SuSE、Debian 和 Mandrake,都有与这些发行版的库存内核配合使用的 FreeS/WAN 软件包。对于 Red Hat 7.3 的用户,可以从 Steamballoon rpms.steamballoon.com/freeswan 下载启用 IPSec 内核的 RPM 软件包(二进制和源代码)以及 FreeS/WAN 设置工具。
由于我个人最常运行 SuSE 和 Red Hat,因此我将描述如何为它们获取和安装 FreeS/WAN。如果您的需求更复杂,请参阅 www.freeswan.org/doc.html 上的文档。根据您的内核和发行版,您可能需要从源代码编译 FreeS/WAN,但这在网站上有详细的文档。
如果您运行带有库存内核的 SuSE,只需从 sec 系列安装软件包 freeswan.rpm。确保 ipsec.o 模块的内核版本与您运行的 SuSE 内核的版本匹配。快速检查系统内核版本的方法是使用命令 uname -av。要查看尚未安装的 freeswan.rpm 软件包的内核版本,请使用以下命令
rpm -ql -p ./freeswan.rpm |grep ipsec.o
内核版本将由此文件的路径名指示,例如,/usr/lib/modules/2.2.18/ipv4/ipsec.o。
如果内核版本匹配,请使用 rpm 安装软件包,如下所示
rpm -Uvh ./freeswan.rpm
接下来,通过打开 /etc/rc.config 并将变量 START_IPSEC 设置为“yes”来启用 IPSec。
现在是时候替换可能由 FreeS/WAN RPM 安装在您的系统上的示例主机密钥(RSA 签名密钥对)了。(如果 /etc/ipsec.secrets 的创建日期早于今天的日期,则您需要新密钥。)对于 FreeS/WAN 1.92 及更高版本,执行此操作的命令是
mv /etc/ipsec.secrets /etc/ipsec.secrets.test ipsec newhostkey --hostname --output /etc/ipsec.secrets --bits 2192
您当然需要将 my.host.FQDN 替换为主机的完全限定域名,例如 george.wiremonkeys.org。
对于早期版本的 FreeS/WAN,请使用
ipsec rsasigkey --hostname my.host.FQDN 2192 \
> /etc/ipsec.newkey
如果您使用 ipsec rsasigkey 命令,您还需要使用文本编辑器打开 /etc/ipsec.secrets,并将花括号 ({}) 之间的所有内容替换为 ipsec.newkey 的内容(或您将新密钥 cat 到的任何文件)。
即使您尚未配置它,您现在也可以通过启动和查询 FreeS/WAN 来对其进行测试
/etc/init.d/ipsec start ipsec whack --status
如果第二个命令 (ipsec whack --status) 返回 000,则您的 FreeS/WAN 安装工作正常。
如果您运行带有库存内核(在撰写本文时为 2.4.18 版本)的 Red Hat 7.3,请从 rpms.steamballoon.com/freeswan 下载相应的启用 IPSec 的内核软件包。您应该抓取 freeswan 的二进制或源软件包。首先安装内核软件包。
如果您已经安装了库存内核软件包(几乎可以肯定您已经安装了),则需要使用 --force 选项,因为 Steamballoon 的 FreeS/WAN 内核软件包的基本名称(简称为 kernel)与官方 Red Hat 库存内核的名称相同。在我的基于 Celeron 的 Red Hat 7.3 系统上,我像这样安装了 Steamballoon 内核软件包(示例中的所有版本号可能都已过时)
rpm --force -i ./kernel-2.4.18-3ipsec.i686.rpm
不用担心强制安装;新内核的映像文件和模块目录的名称是唯一的,并且 不会 覆盖您的旧内核。例如,在我的 Red Hat 7.3 系统上,新的映像文件和模块目录分别命名为 /boot/vmlinuz-2.4.18-3ipsec 和 /lib/modules/2.4.18-3ipsec。Steamballon 的 RPM 安装后脚本使用新 IPSec 内核的条目覆盖了 /boot/grub/grub.conf 中旧内核的启动菜单条目(即,它从启动菜单中删除了旧内核)。但是在为旧内核重新添加菜单条目后,我可以选择在启动时选择任一条目,没有任何问题。
安装内核软件包后,安装用户空间工具。在我的系统上,命令是
rpm -i freeswan-1.97-0.i386.rpm
此 RPM 安装了一个启动脚本 /etc/init.d/ipsec,但未启用它。您可以像这样启用它
chkconfig --add ipsec接下来,按照上一节中的描述生成新的 RSA 签名密钥对。然后,您可以启动并测试您的 FreeS/WAN 安装,上一节中也对此进行了描述。
本月,我只有足够的篇幅来介绍一种常见的 FreeS/WAN 场景:无线 LAN 隧道,如图 2 所示。图 4 显示了图 2 中网络的一部分,这次带有 IP 地址。在此示例中,无线客户端系统是动态 IP 地址。正如我们稍后将看到的,您不需要知道所有潜在客户端的 IP 地址。
本文的其余部分取决于几个重要的假设:1) 基本网络连接已经到位,因此无线客户端可以连接到 Linux 服务器;2) 基本数据包转发工作正常——无线客户端可以访问无线网关另一侧的主机;3) 网关尚未充当防火墙。
我做出第三个假设完全是为了权宜之计。良好的安全性是分层的,限制传入的 VPN 流量可以和不可以去哪里不会花费您任何代价(除了少量的设置时间)。不幸的是,我无法在此处深入探讨;有关更多信息,请参阅 www.freeswan.org/doc.html 上的“FreeS/WAN 防火墙快速入门”HOWTO。
FreeS/WAN 通过两个文件进行配置:/etc/ipsec.conf 是其主配置文件,/etc/ipsec.secrets 是其密钥存储库。这两个文件都应具有限制性权限;0600 是一个安全的选择。特别是 /etc/ipsec.secrets 必须小心保护。如果您需要从该文件中复制任何数据,例如,您主机的公共 RSA 密钥,请仅将您需要的数据复制到单独的文件中。永远不要让 ipsec.secrets 本身离开您的系统。我们将在下个月更深入地讨论此文件。
清单 1 显示了示例无线 VPN 客户端中的 ipsec.conf 文件。/etc/ipsec.conf 由三个部分组成:基本设置参数 (config setup);默认隧道参数 (conn %default);以及隧道定义 (清单 1 中的 conn george-gracie,其中 george-gracie 是我为该隧道选择的名称)。
在单接口系统上,config setup 部分的默认设置可以安全地保持不变。其中最重要的参数是 interfaces。这告诉 FreeS/WAN 使用哪个接口作为 IPSec 隧道的本地端点。它的默认值是 magic string %defaultroute,它扩展为 ipsec0=[interface](其中 [interface] 是系统中默认路由中指示的网络接口名称,例如,eth0)。类似地,默认隧道设置通常也可以保持不变。
这使我们来到了 ipsec.conf 的核心:隧道定义。在清单 1 中的隧道 george-gracie 中,我们首先设置 authby,它确定 IPSec 主机如何相互验证身份。默认值为“secret”,它是预共享密钥的缩写。此设置允许您定义在透明质询-响应身份验证事务中使用的密钥字符串。密钥本身永远不会遍历网络,因此这不像您想象的那么马虎的身份验证方法。
但这现在无关紧要,因为在清单 1 中,authby 设置为 rsasig,因此使用 RSA 身份验证。RSA 身份验证不一定更安全,但它更方便。共享密钥必须事先通过某些安全方式(例如 PGP 电子邮件或 SSH)交换,而 RSA 身份验证中使用的公钥可以公开交换(甚至发布在网页上)。
left 和 right 的概念在 FreeS/WAN 配置中很重要;它们在参数和命令中用于指定 IPSec 隧道的端点。哪一侧是哪一侧并不重要,只要您保持一致即可。同一主机应在两个系统的隧道定义中都为 right,并且一个系统 不应 反转在另一个系统上定义的 right/left 指定。
为了理智起见,只要一个主机充当另一个主机的服务器,就鼓励您将该主机指定为 left。在我们的示例中,George 充当无线客户端的服务器,因此 George 是 left,而 Gracie,客户端系统,是 right。
隧道配置参数 left 指示隧道左端点 George 的 IP 地址,其 IP 地址为 10.0.54.2。当然,Right 指定右端点的 IP 地址。但是在我们的场景中,Gracie 和其他无线客户端具有动态 IP 地址。因此,我们不指定 IP,而是使用 magic string %defaultroute,它扩展为主机默认路由中指定的接口的 IP 地址。
隧道参数 leftid 可能看起来是多余的,因为我们刚刚用 left 标识了左侧 IP 地址,但它略有不同。leftid 和 rightid 指定每个隧道端点的身份验证 ID。这可以是 IP 地址,也可以是以 @ 符号开头的 FQDN。由于 Gracie 的 IP 地址是动态的,因此 @gracie.wiremonkeys.org 是 leftid 的唯一可行值。但是在本例中,@george.wiremonkeys.org 和 10.0.54.2 是 rightid 的可互换值。
清单 1 中要考虑的下一个隧道参数是 leftsubnet。这定义了哪些目标 IP 可以接收来自右侧的数据包,因此也定义了右侧端点将使用隧道的哪些目标。由于 Gracie 和其他无线客户端将使用 George 作为他们通往公司 LAN 和整个世界的唯一网关,因此我们将其设置为 0.0.0.0/0,这表示所有目标。(还有一个 rightsubnet 参数,但是您只需要在站点到站点场景中设置两个子网参数。在远程访问和其他客户端/服务器设置中,只需要其中一个。)
当您为隧道指定 RSA 身份验证时,leftrsasigkey 和 rightrsasigkey 都是必需的。这些的值存储在每个主机的 ipsec.secrets 文件中,在以 #pubkey= 开头的行中。或者,您可以使用以下命令
ipsec showhostkey --left
或
ipsec showhostkey --left--left 和 --right 选项(在 FreeS/WAN 1.9 及更高版本上有效)是可选的,但很方便。它们使输出采用 leftrsasigkey 或 rsasigkey 语句(分别为)的形式,可以逐字复制并粘贴到 ipsec.conf 中。例如,在 George 上运行 ipsec showhostkey --left 将返回清单 1 中的 leftrsasigkey 语句。在 Gracie 上运行 ipsec showhostkey --right 将返回 rightrsasigkey 语句。请注意,尽管 RSA 密钥很长,但每个密钥都必须占用一行,即没有换行符。
清单 1 的隧道语句中的最后一个参数是 auto,它告诉 FreeS/WAN 在启动 IPSec 时对隧道执行什么操作(如果有的话)。值为 start 会导致隧道自动初始化和启动。“add”导致将其添加到 IPSec 守护程序(称为 pluto)的连接规范中,“ignore”导致隧道被忽略。在清单 1 中,auto 设置为 start。因此,每当在 Gracie 上启动 IPSec 时,我们都希望立即启动与 George 的隧道。必须正确定义 config setup 参数 plutoload 和 plutostart,auto 才能具有任何相关性——有关更多信息,请参阅 ipsec.conf(5) 手册页。
好的,客户端 ipsec.conf 就到此为止。但是 George 呢?碰巧的是,在这种情况下,双方的配置几乎相同。清单 2 显示了 George 的大部分 /etc/ipsec.conf 文件。
第一个区别是,与 Gracie 不同,George 有多个接口,因此有必要为 interfaces 参数提供显式值。George 的默认路由中的接口面向公司 LAN,而不是无线 LAN,因此 %defaultroute 的值将不起作用。接下来,我们有一个新的 config setup 参数 forwardcontrol。当设置为 yes 时,它告诉 IPSec 在需要时打开 IP 转发,并在关闭 IPSec 时关闭它。
接下来,在隧道部分本身中,right 现在设置为 %any 而不是 %defaultroute(因为 %defaultroute 将返回 George 的本地 IP,而不是 Gracie/right 的)。并且,auto 设置为 add 而不是 start,因为 George 充当服务器;它只需要准备好让 Gracie 启动隧道。
现在是关键时刻!首先在 George 上,然后在 Gracie 上,我们输入命令
ipsec setup restart
George 将读取 /etc/ipsec.conf,将 george-gracie 隧道定义加载到其连接设置数据库中,并等待连接。Gracie 将执行相同的操作,然后启动隧道。启动消息将记录到 /var/log/messages 或 /var/log/secure。如果在客户端系统上,ipsec setup restart 的输出以“IPsec SA established”消息结尾,则您的隧道已启动!尝试 ping 或以其他方式连接到远程网络上的主机;连接的行为应该与您启动隧道之前没有什么不同。实际上,您可能需要在隧道路由的以太网接口上运行 tcpdump,以确保仅发送 ESP(封装安全有效负载)数据包(即,加密的隧道数据包,而不是实际的 Ping、FTP 数据包等)。
下个月,我们将再看看一两个 VPN 场景,并更深入地探讨 FreeS/WAN 的辉煌。希望这足以让您开始走上安全无线网络的道路!
Mick Bauer (mick@visi.com) 是明尼苏达州明尼阿波利斯市 Upstream Solutions, Inc. 的网络安全顾问。他是即将出版的 O'Reilly 图书《使用 Linux 构建安全服务器》的作者,“网络工程波尔卡舞曲”的作曲者和一位自豪的家长(孩子们的家长)。