虚拟专用网络的工作原理,第 1 部分

作者:David Morgan

商业虚拟专用网络 (VPN) 产品正变得日益普及。它们让机密数据可以安全地搭乘互联网的“顺风车”,弥补了互联网固有的安全缺陷。Linux VPN 可以通过多种方式构建。Arpad Magosanyi 在其巧妙而简洁的 VPN mini-HOWTO 中概述了一种方法。我为一家企业实施了该方法,并在此介绍我获得的一些见解。

本文第 1 部分为理论性和解释性,第 2 部分为实践性。我首先定义 VPN 并描述它们采用的技术。我将讨论 HOWTO 用于构建 VPN 的 Linux 构建块的组合。在第 2 部分中,我将展示日志和屏幕输出,描述实际运行构建 VPN 的脚本的结果。

虚拟专用网络

VPN 使用公共传输网络(互联网)进行私密通信。它应用加密来保护隐私。传统上,公司一直使用专用线路进行私密通信,即专用电话线。保持电子对话私密的两种方法是使线路私密和数据私密。专用线路是私密的,因为线路是私密的,即其他人无法访问。VPN 是私密的,因为数据是私密的,即通过加密变得不可理解——不同的手段,相同的结果。

VPN 最常用于连接同一公司不同站点的两个网络。该技术实际上是将远程计算机插入本地网络,将两个物理网络合并为一个逻辑网络。远程计算机可以访问与本地计算机相同的本地资源。同时,远程机器享有与本地机器相同的隐私程度。所有这些在操作上(虽然在性能上并非如此)都是位置透明的,就好像它们连接到本地网络一样。这种在网络之间实现完全参与和完全隐私的组合,同时使用非私有链接,是 VPN 的标志。VPN 最具吸引力的地方在于它很便宜。专用线路很昂贵,因此用免费传输网络取代它们是经济的。

网络——PPPD 和 ROUTE

HOWTO 中的 VPN 由两个主要成分构成:安全外壳 (ssh/sshd) 和点对点协议 (pppd)。一台机器(我的术语中的“本地”机器,Magosanyi 先生的“主”机器)运行 HOWTO 的脚本来呼叫另一台机器(我的“远程”机器,他的“从”机器)。我将这些称为 VPN 服务器。其理念是它们属于要加入的两个网络,并充当它们之间代表任何想要对话的远程工作站对的联系点或数据管道。

Workings of a Virtual Private Network, Part 1

表 1. VPN 布局

表 1 中的图表描述了 VPN HOWTO 第 4.1 节中的布局和地址。对于公共互联网地址(fellini-out、polanski-out),我已替换为我在生成本文后面显示的屏幕截图和日志片段时实际有效的地址,以保持一致。

为了构建 VPN,本地 VPN 服务器上的脚本必须执行四个主要命令,其中两个命令在远程 VPN 服务器上

  • pppd 远程,在另一个 VPN 服务器上以某种方式触发

  • pppd 本地,在运行脚本的 VPN 服务器上

  • route 本地

  • route 远程

pppd 命令建立工作连接。这严格来说是 VPN 服务器之间的一条双边脐带,不会将相互连接扩展到网络上的工作站。这是通过 route 命令完成的。一旦执行这些命令,两个网络就已透明地合并为一个由机器组成的组,所有机器都通过互联网地址相互可见。

私密性——SSH

隐私来自第一台计算机用于触发第二台计算机上的命令的工具,因为该工具还执行身份验证和加密。它被称为安全外壳程序,它是一个远程命令执行器和一个加密器。实际上,它是一对程序,ssh 和 sshd,专门设计用于在客户端-服务器模型上协同工作。使用该模型的其他常用程序包括 ftp/ftpdtelnet/telnetd 以及任何浏览器/httpd

sshd、ftpd 和 httpd 中的“d”代表守护程序,是服务器的同义词。服务器程序就像精灵,可以满足其客户端/请愿者的各种愿望。因此,ftpd 向 ftp 客户端授予文件愿望,而 httpd 向浏览器客户端授予网页愿望。同样,sshd 向 ssh 客户端授予远程命令愿望。此外,ssh 和 sshd 的编写目的是加密和解密在它们之间传递的所有流量。

作为命令执行器,ssh 可以处理单个命令并退出。或者,它可以设置一个开放式登录会话,用户可以在其中临时提交命令。在这两种情况下,ssh 都会将它告诉 sshd 在远程机器中运行的命令的标准输出返回到本地机器。用户实际坐在本地机器上,逻辑上以远程机器的用户的身份登录并运行。所有命令或会话输出都从远程机器传送到他的本地监视器。这很像 telnet。与 telnet 不同,一切都在会话期间动态加密和解密。

ssh 手册页的第一句话突出了这些作用

ssh(安全外壳)是一个用于登录远程机器并在远程机器中执行命令的程序。它旨在取代 rlogin 和 rsh,并在两个不受信任的主机之间通过不安全的通道提供安全的加密通信。

设置远程登录会话的语法是

ssh  -l
执行单个远程命令的语法是
ssh  -l
-l 代表“登录”,并指定远程计算机登录的用户名。第一个命令形式使您以 remote-user 的身份登录到另一台机器,并在您的屏幕上显示他的登录提示符。第二个命令形式也让您登录,并一举在远程机器上启动 command。当命令在后一种情况下终止时,您的连接也会终止。如果 commandls /home,则另一台机器的 /home 子目录的列表将传送到您的屏幕。以下是它的实际屏幕截图
# ssh  -l slave  206.170.217.204  ls /home
david
ftp
httpd
panderson
samba
slave
登录提示符是用户所坐的本地机器的提示符。输出来自远程机器,其中运行了 ls(作为该机器上名为 slave 的用户),但此处显示在本地监视器上。它显示了在远程目录 /home 中找到的内容。

请注意,执行未受到密码质询的阻碍。对于一个应该提供安全性的程序来说,这令人惊讶。但是,ssh 确实以另一种透明的方式进行了身份验证;它的技术使用公钥密码术,称为 RSA 身份验证。我将向您展示来自远程机器的日志文件的证据,然后解释密钥的工作原理。

与上述本地活动同时,这些条目出现在远程机器的日志文件 (/var/log/messages) 中

Nov  7 20:15:54 localhost sshd[1400]: log: Connection from 206.170.218.30 port 1023
Nov  7 20:15:57 localhost sshd[1400]: log: RSA authentication for slave accepted.
Nov  7 20:15:57 localhost sshd[1402]: log: executing remote command as user slave
Nov  7 20:15:58 localhost sshd[1400]: log: Closing connection to 206.170.218.30
Nov  7 20:15:58 localhost PAM_pwdb[1400]: (ssh) session closed for user slave

请注意,这些条目是由 sshd 编写的,它是安全外壳程序对的服务器端。这是合理的,因为本地机器上的调用程序是客户端端 ssh。按照设计,ssh 调用并请求 sshd 进程,通过 sshd 运行的 TCP 端口号(默认情况下为 22,但可配置)连接到它。sshd 随后开始运行,它们继续执行其操作:身份验证和加密。我们刚刚看到了身份验证的辅助证据,尽管到目前为止我们还没有看到加密的证据。两者都依赖于密钥的使用,特别是表征公钥密码术的匹配密钥对。在解释身份验证如何通过使用密钥产生结果之前,让我描述一下基本理论以及如何使用密钥配置 ssh。

首先,这是来自 README.SSH 文件的一个很好的概括总结

启动时,ssh 连接服务器机器上的 sshd,验证服务器机器是否真的是它想要连接的机器,交换加密密钥(以防止外部侦听器获取密钥的方式),使用...RSA 身份验证...执行身份验证。然后服务器(通常)分配一个伪终端并启动一个交互式 shell 或用户程序。

请注意,使用 ssh 的 -v 选项可让您观看这些活动。

公钥/双密钥密码术

公钥密码术是密钥密码术的历史继承者。我称它们为双密钥密码术和单密钥密码术。早期的密码使用完全相同的密钥进行解密和加密。当向收件人发送加密消息时,您还必须以某种方式向他提供密钥,以便能够解密。

阿喀琉斯之踵在于您可能无法使用您尝试保护的同一通信通道来提供密钥。根据预设,它需要保护——有关它的信息可供其他人使用。其他人无法渗透您计划发送的加密消息取决于对他们保密您的密钥。但是,如果您通过该通道将其发送给您的预期收件人,那么实际上您也在将其发送给其他人,从而破坏了您的目的。这种密码类型的术语“密钥”反映了它对其密钥保密的要求,以便它可以工作。

使用公钥密码术,有两个密钥:一个加密器和一个数学上对应的解密器。一个人永远不会泄露解密器。相反,他分发加密器。与密钥不同,它不解密任何东西。它不具备解密能力或价值。因此——敲鼓——即使它被公开拦截也没关系。

此外,各方——发送者/加密者和接收者/解密者——角色颠倒。即将成为接收者的人,而不是发送者,生成密钥。并且是他,而不是发送者,将必要的(加密器)密钥分发给另一个人。安全性来自这样一个事实,即“权力”密钥——解密器——从一开始就与接收者在一起,并在需要它的地方,并且永远不需要传输。传输风险由此消除。阿喀琉斯之踵解决了。

SSH 身份验证

现在让我们看看 ssh 如何使用公钥密码术进行 RSA 身份验证,以及它如何处理加密。它有一个实用程序 ssh-keygen,可以生成匹配的密钥对并将它们写入磁盘文件。通常,每个希望使用 ssh/sshd 的用户都会生成自己的密钥对,无论是主动地通过在其他计算机上运行命令,还是被动地通过让其他计算机的用户使用他的用户名登录以运行命令。ssh-keygen 将两个密钥文件写入已登录用户的家目录。文件 identity.pub 包含适合分发给其他人的公钥,并且是纯 ASCII 码。文件 identity 包含要保密的私钥。用户只需运行一次 ssh-keygen。表 2 是这些和其他一些重要的 ssh 文件(并非此处讨论的所有文件)的布局。

表 2

用户身份验证充当用户密钥文件之间的交互。(ssh 还提供主机身份验证,涉及 /etc/ssh/ssh_host_key,此处未讨论。)我指的是始终参与 ssh 连接的两个用户。首先,当您从本地机器运行 ssh 时,您已经以某个身份登录到它。其次,使用 ssh 命令中的 -l 选项,您可以指定远程机器上的某个目标用户作为那里的操作员。我将这些称为本地用户和远程用户。每个 ssh 用户的家目录中的另一个与密钥相关的文件是 authorized_keys。为了成功,RSA 身份验证必须在远程用户的 authorized_keys 文件中找到本地用户的公钥副本。除非是故意的,否则这种情况永远不会发生。如果我作为本地用户,希望能够以您的身份登录到您的机器,我会将我的公钥发送给您。我可以将我的 identity.pub 的副本作为文件发送给您,或者将其内容嵌入电子邮件消息中(因为它纯粹是 ASCII 码,并且密钥传输的安全性并不重要)。然后,您作为远程用户,将使用编辑器将我的公钥放入您的 authorized_keys 文件中。现在,当我使用 ssh 以您的身份登录到您的机器时,授权将成功。相反,如果我想让您以我的身份登录到我的机器,您将向我发送您的公钥,我将将其放入我的 authorized_keys 文件中。

远程机器上的 sshd 进行身份验证时,使用本地用户的公钥加密某些内容,并将其发回本地机器。然后,本地机器必须通过解密并发送回与原始数据匹配的数据来证明自身。此时,身份验证完成。sshd 将“RSA authentication for remote-user accepted”写入远程日志(如上所述),并让会话或命令继续进行。对于实施目的,您只需在配置计算机以通过 ssh 交互时遵循密钥预置规则。

正如我们之前注意到的,此方法不涉及任何密码。它只关心“请愿”用户是否可以令人信服地提出预期的公钥,然后证明他拥有匹配的私钥。虽然这违反直觉,但我经常在没有密码的情况下登录到远程机器——以 root 用户身份!

ssh 提供其他身份验证方法,包括密码检查(ssh 功能广泛,其配置文件中有更多选项)。这些方法可以代替或与 RSA 身份验证结合使用。对于 VPN 的目的,考虑到 RSA 身份验证满足大多数人的充分安全性测试,因此首选单独使用它,因为它具有透明性。

ssh 加密

身份验证后,本地用户可以作为远程机器上的指定用户自由操作。在那里,sshd 代表他运行请求的命令或 shell,并将任何标准输出发送回本地机器,但首先对其进行加密。机器之间的直接对话完全在 ssh 和 sshd 之间进行。因此,ssh 在接收端,知道如何处理传入的数据流(解密它)以及如何处理(使用约定的密钥)。反向流量也是如此,ssh 加密,sshd 解密。

您可能会认为每台机器上用于出站数据的加密密钥将是另一台机器用户的公钥。但是,出于性能原因,ssh 和 sshd 在其初始协商阶段改为采用不同的密钥,并在整个会话中使用同一密钥进行加密。虽然 ssh-keygen 的公钥/私钥在身份验证中起着核心作用,但它们在加密中的作用仅在于不可穿透地加密此密钥的初始交换,从而克服了密钥密码术中的密钥交换弱点。但是,对于正在进行的消息加密,不使用公钥/私钥。密钥算法比公钥/私钥算法更快。安全交换的密钥(称为“会话密钥”)用于加密会话的其余部分。

重要的一点是,一旦会话开始进行,ssh 和 sshd 就会作为透明的中间进程运行,从而使整个会话得到加密。机器之间不会传输未加密的内容,因此有意义的拦截是不可能的。

混合成分

现在我们可以将 VPN 组合在一起了。诀窍是战略性地提交某个命令以供 ssh 远程启动。该命令是 pppd,即点对点协议守护程序。

我们知道,在会话期间,ssh 和 sshd 会加密它们启动的任何命令的整个数据流,因为它在它们之间传递。会话的持续时间与命令执行所需的时间一样长。因此,对于像 ls /home 这样直接运行到终止的命令,会话是短暂的,因为命令是短暂的。并非所有命令都如此迅速,例如,编辑器或 pppd。

ssh  -l

此命令整天都保持运行状态——您必须终止它才能停止它。

对于实现 VPN 功能至关重要的是,pppd 本身是其他程序的流量载体。这意味着通过在 ssh 控制下启动的 pppd 接口在两台计算机之间传递的所有内容都会自动通过加密处理。

虚拟性

与路由相结合,这种双边脐带链路扩展为一个通用桥梁,可以承载相对两侧的任何一对工作站之间的对话。路由让一个 LAN 上的每个工作站都可以通过 IP 地址 看到 另一个 LAN 上的工作站——一个幸福的大家庭。同时,ssh 拒绝外部世界看到这种可见性。这正是让所有工作站都在本地的效果。通过这种设置,您拥有相当于单个 LAN 的东西,但由于这并不是您真正拥有的东西,因此您的合并网络是“虚拟”的。

相对 LAN 上的工作站可以在这里做什么?同一 LAN 上的一对工作站可以做的任何事情——更普遍地说,任何可以通过 IP 地址相互寻址的机器都可以做的事情。根据我的经验,Linux VPN 上远程机器对之间实际操作的示例包括

  • Microsoft 计算机进行 MS 对等资源共享。

  • 一台 Linux 机器通过运行 Samba 向 MS 机器提供资源。

  • 一台 MS 机器在 IBM AIX UNIX 机器上运行终端仿真器。

  • 一台 Linux 或 MS 机器使用 TELNET 登录到另一台 Linux 或 UNIX 机器。

交互机器不知道它们的对话在很大程度上被加密。它们只是通过 IP 地址相互启动数据包,并让它们的路由表找出答案。当数据包到达它们的 VPN 服务器时,那里的路由表会将这些数据包指向由 ssh 操作的 ppp 接口。这就是安全性的来源;否则,它只不过是通常的路由。

这就是理论的全部内容。它是虚拟的。它是私密的。它是一个网络。因此,我相信您会同意,它是一个虚拟专用网络。第 2 部分将详细介绍 VPN HOWTO 脚本的实际操作。

资源

Workings of a Virtual Private Network, Part 1
David Morgan 是洛杉矶的独立顾问,也是圣莫尼卡学院的计算机科学讲师。他在 1998 年开始认真对待 Linux。在等待 Linux 进入他的生活时,他获得了物理学和商业学位,在美国和平队担任教师,曾在 Rexon Business Machines、Nantucket Corporation、Computer Associates 和 Symantec Corporation 担任技术和产品管理职位。他骑自行车、背包旅行和烹饪。请将您的食谱和 VPN 经验发送给他。可以通过 dmorgan1@pacbell.net 与他联系,目前维护的网站为 http://www.geocities.com/Yosemite/Gorge/3645/http://skydesign.hypermart.net/
加载 Disqus 评论