ssh: 安全 Shell
ssh 程序套件是在互联网上的主机之间建立安全通信通道的一种有趣方式。它取代了一些常用的通信通道(如 telnet、rlogin、rsh 和 rcp),并通过一种新的安全协议提供等效的功能。本文旨在向用户介绍 ssh 的功能,并不 претендовать 成为安全问题的权威教程。
首先,像往常一样处理加密材料,让我们先抛出一些法律声明。该软件包的 Unix 实现版本是免费分发的,供非商业用途使用,可以从世界各地主要的 ftp 站点检索。 “非商业用途”的含义在 ssh 发行版中的 COPYING 文件中得到了很好的说明。非商业用途包括在互联网上工作的人员使用该工具,前提是 ssh 不得用作销售论据。但是,获得许可证的允许并不足以使用该软件包。您还必须确保您的政府允许使用加密材料:一些国家禁止公民使用任何类型的密码学。
就标准化而言,IETF(互联网工程任务组)正在研究 ssh 的想法。这意味着该协议将要被标准化,并将始终保持彻底的文档化。任何人都可以重新实现该软件并以不同的复制策略分发她的版本。尽管目前还没有关于 ssh 的 RFC,但已经有三个互联网草案可用,它们记录了该协议的不同方面。我在六月份下载的草案将于 1997 年 9 月 1 日到期,但新的草案(或真正的征求意见稿)将在那时之前发布。
ssh 的主要目的是克服 TELNET 和类 rsh 协议的安全问题。这些协议虽然被广泛使用,但在安全方面非常薄弱:TELNET 通过网络传输明文密码,而 rsh 及其同类协议很容易被欺骗技术破解(熟练的系统管理员或任何可以物理访问线路的人都可以利用 .rhosts 文件来获得对远程计算机的访问权限)。 ssh 协议通过在通信方之间强制执行强大的身份验证方案来解决这些漏洞。
该协议不仅对客户端主机进行服务器身份验证,还强制加密通过已建立的通信通道发送的所有数据。虽然加密需要在通信主机中进行一些计算负载,但用户可以确信,没有嗅探器可以理解网络数据包,也没有人可以伪造数据包来获得对服务器的访问权限。
最后,该协议旨在允许将其他通信通道封装在 ssh 流中,以便非加密协议可以免费受益于 ssh 的功能。此功能对于建立安全的 X11 连接最有用,但其用途比仅仅安全方面要灵活得多。
就用户界面而言,新程序被设计为 rsh、rlogin 和 rcp 的直接替代品。虽然系统管理员至少需要处理 ssh 问题才能安装软件包,但最终用户可以愉快地忽略底层通信机制已更改的事实。
当前版本的 ssh,在我撰写本文时,是 1.2.20。它随附 configure 脚本一起分发,因此
./configure && make && make install
完成了软件包的完整安装工作。即使 /usr/local 属于您,您也需要成为特权用户才能安装 ssh。此要求是必要的,因为服务器和一些客户端程序都必须能够打开特权 TCP 端口。此外,该软件包将其系统范围的文件安装在 /etc 目录中。如果您必须在不以特权用户身份安装程序的情况下运行 ssh 会话,您应该首先阅读 FAQ 文件,其中描述了如何在没有太多麻烦的情况下完成此操作。
该程序套件由一个服务器程序、几个客户端和一对支持工具组成。为了成为 ssh 服务器,建议的操作是在计算机启动时从您的初始化文件中调用 sshd。该程序默认安装在 /usr/local/sbin 目录中,它监听本地主机的 22/tcp 端口以接受传入连接。如果 /etc/services 文件中尚未包含以下行,则应添加类似下面这样的行
ssh 22/tcp # secure shell
可以从 /etc/inetd.conf 运行 sshd,方法是将 -i 标志传递给守护程序。不鼓励这种做法,因为守护程序可能需要几秒钟才能启动,因为它每次启动时都会生成一个加密密钥。
在客户端,在安装时无需执行任何操作即可启用服务的使用。安装后,可以在 /usr/local/bin 目录中找到几个程序,任何人都可以执行这些程序。以下是这些程序的列表
ssh (slogin):ssh 客户端程序的行为类似于 rsh,因为它在远程主机上执行命令,将其自身的 stdin、stdout 和 stderr 重定向到远程主机。如果命令行中仅指定一个参数,则将其视为远程主机,并且 ssh 在该主机上打开一个终端会话,就像 rlogin 所做的那样。slogin 客户端只是 ssh 的一个符号链接。通常,系统会要求用户提供密码以在远程主机上进行身份验证。
scp:“安全复制”是“远程复制”的替代品。它使用相同的语法并执行相同的任务,具有 ssh 提供的相同的安全增强功能。通常会提示用户输入密码以执行身份验证。
ssh-keygen:此程序生成与调用它的用户关联的新密钥。生成的公钥和私钥默认保存在 $HOME/.ssh/ 目录中,在两个名为 identity 和 identity.pub 的文件中。当您希望从外部安全登录到本地主机而无需提供密码时,需要一对密钥。
ssh-agent:此程序旨在管理用户会话的安全性。它存储用户的私钥,并且可以被任何子进程联系。有关 ssh-agent 的更多信息,请参阅手册页。
ssh-add:此程序将身份添加到身份验证代理。ssh-agent 必须是运行 ssh-add 的进程的祖先,以便它们能够通信。
ssh-askpass:这个简短的程序在内部被 ssh-add 和 ssh-keygen 使用,以使用 X 图形环境询问密码短语。
make-ssh-known-hosts:此 PEl 脚本检索域中所有主机的公钥;它查询 DNS 并与属于域的主机通信。此程序更新 /etc/ssh_known_hosts 文件以保存新密钥。应定期运行该程序,通常通过 cron,以反映主机公钥的任何更改或本地网络中主机上 ssh 的新安装。
虽然安装文件的数量可能会吓到新手用户,但只要您仅使用普通的 ssh 和 scp 客户端程序,就没有什么新东西需要学习。系统管理员甚至可以选择用 ssh 替换 rsh,用 scp 替换 rcp,以便安全操作对最终用户完全透明。实际上,这种替换并非完全透明,因为 ssh 引入了一个普通 rsh 或 rlogin 中没有的新功能:X11 转发。此功能被认为是使用 ssh 协议的“副作用”,将在下一节中描述。
其他程序的作用是次要的。它们有助于建立良好的工作环境,以避免在正常操作期间键入过多的密码,而又不损害系统安全。虽然了解它们的内部原理对于程序操作不是必需的,但快速浏览文档可能会提供有关当前加密技术的有趣见解,并有助于配置主机以自动化登录过程。
ssh 协议被设计为灵活的,并支持在单个 TCP 流中多路复用多个通信通道。这种设计选择导致了两个结果:一方面,协议的实现比其他基于 TCP 的协议复杂得多,另一方面,最终用户可以利用增加的灵活性来实现新的目标。这些目标之一是在 X 服务器和客户端应用程序之间建立安全通信通道。每当建立 ssh 会话时,默认情况下都会启用此功能。
X11 转发背后的想法非常简单。 ssh 应用程序在本地运行,并且能够连接到本地 X 服务器,而无需诉诸网络(通过本地 Unix 域套接字)。另一方面,远程图形程序可以在本地连接到生成远程 shell 的 sshd 服务器(通过环回网络接口)。远程 sshd 可以将图形数据封装在它拥有的安全通信通道中,以完成连接图形应用程序和 X 服务器的路径。
图 1 显示了远程 X 应用程序(在名为 sandra 的计算机上运行)如何安全地连接到本地 X 服务器(在 morgana 上)。
当您通过 ssh 登录到远程计算机时,DISPLAY 环境变量会自动设置为正确的值,并且无需用户干预即可建立图形通道。以下屏幕截图显示了 DISPLAY 的自动分配
morgana% ssh sandra env | grep DISPLAY DISPLAY=sandra.systemy.it:10.0
很明显,ssh 会话在 sandra 上调用的任何图形程序都将连接到本地显示器(即 sandra:10)。
ssh/sshd 程序还可以根据用户的需要转发其他 TCP 通道。可以通过为客户端 ssh 程序指定命令行开关来激活此功能。我不会在此处描述这些机制,因为 ssh 的手册页写得很好。
通过不安全网络建立连接时的主要问题是执行可靠的身份验证。 ssh 软件包对身份验证非常讲究,您将被要求比平时更频繁地输入密码。一遍又一遍地输入密码令人痛苦,并且可以通过正确配置系统文件来避免。另请注意,您键入的任何密码都是在建立加密通信通道之后传输的。
您可以键入 ssh -v(详细)以获取有关正在发生的事情的报告。如果您意外地被要求输入密码,则返回的信息非常有用。现在,让我们看一下 ssh 为验证远程服务器中的用户身份而执行的步骤。
首先,如果目标帐户没有密码,则授予访问权限。如果有密码,则会尝试不同类型的身份验证引擎;每种引擎都可以在服务器中启用或禁用。例如,默认情况下,“PasswordAuthentication”和“RhostsRSAAuthentication”已启用,“RhostsAuthentication”已禁用。
以下是当您尝试登录到以默认配置运行的服务器时(可以在 /etc/sshd_config 中更改)的操作顺序。
客户端接收服务器的公钥。如果无法识别,ssh 会交互式地询问用户是否必须继续连接。通过确认,用户信任远程主机与其名称匹配,并且服务器的公钥保存在客户端的 $HOME/.ssh/known_hosts 文件中。如果系统范围内已知服务器主机(即,它出现在 /etc/ssh_known_hosts 中),则不会执行此步骤。
客户端尝试通过“RhostsRSA”进行身份验证。这要求“Rhosts”身份验证成功:用户主目录中的 .rhosts 或 /etc/hosts.equiv 允许登录。sshd 在检查这些文件时比 rlogind 更为讲究,如果任何文件是组可写或世界可写的,则拒绝权限。不用说,任何文件中以“加号”字符开头的条目都被忽略。此外,如果用户的主目录是组可写或世界可写的,则甚至不使用 .rhosts,并且 /etc/hosts.equiv 不用于授权 root 登录。除了标准文件外,sshd 还检查用户主目录中的 .shosts 和 /etc/shosts.equiv。如果您仍然希望通过信任比通过 ssh 信任的主机更少的主机在服务器主机上运行 rshd 或 rlogind,这些文件很有用。
如果上一步成功,则尝试 RSA(随机状态身份验证)。此技术包括客户端向服务器发送质询,服务器必须正确回复。质询由使用客户端私钥加密的随机数据组成;服务器必须解密此类数据并返回其校验和。仅当服务器知道客户端的公钥时,服务器才能解决质询,只有当远程用户同意信任客户端(本地)主机时,才会知道客户端的公钥。 RSA 用于防止授权伪造 DNS 记录或临时窃取受信任主机 IP 地址的不受信任主机。
如果之前的任何步骤失败,即如果“RhostsRSA 身份验证”作为一个整体失败,则客户端会恢复为“密码身份验证”,方法是向本地用户请求密码。
如果您的 .rhosts 文件配置正确,但仍然提示您输入密码,则问题很可能是由 RSA 未成功引起的。在服务器中存储客户端公钥的最简单方法是立即调用 ssh 以连接回客户端计算机。当确认继续连接时,服务器(现在充当客户端)会下载本地主机(现在充当服务器)的公钥。
ssh 的设计充满了未来可扩展性的钩子。首先,客户端和服务器在每个部分的开头交换“软件版本”和“协议版本”。虽然“软件版本”主要用于调试问题,但“协议版本”是实现从一个软件版本平滑升级到下一个软件版本的绝佳资源。客户端和服务器都需要支持至少前一个版本的协议,以及当前版本。此要求旨在帮助处理协议增强时的过渡期(这种情况不会经常发生)。当运行 ssh<\!s>-v 时,您可以看到版本字符串的交换等内容。
该协议的另一个出色的设计特点是,可以将新的加密算法(“密码”)添加到基本机制中,而不会失去通用性。这是通过在运行时选择要使用的密码来实现的。在握手期间(通信方交换的前几个数据包),服务器声明它支持哪些密码,客户端选择其中一种密码。每个 ssh 实现都需要支持至少 3DES,以确保可以在任何客户端和任何服务器之间建立安全链接。但是,用户和/或组织可以自由地实现新的密码,并将它们指定为默认选择。一些密码是官方 ssh 发行版的一部分,用户可以在 ssh 命令行中请求特定的算法来覆盖默认值。
该协议还支持会话数据压缩。如果本地网络负载略高,则压缩会话实际上可能比非压缩会话更快。再次强调,压缩是可选的,通信方协商是否使用它。
IETF 认可的标准化工作旨在定义安全 shell 协议的 2.0 版本(ssh-1.2.20 支持的版本称为 1.5)。当前可用的 Internet 草案记录了即将到来的 2.0 协议的三个不同方面
连接协议,draft-ietf-secsh-connect-00.txt),
传输层协议,draft-ietf-secsh-transport-00.txt),
身份验证协议,draft-ietf-secsh-userauth-00.txt。
这些文档非常技术性,但非常值得细读。 IETF 正在研究的协议看起来很有希望,比当前协议具有更大的灵活性。
建议好奇的读者浏览网络以检索有关这些主题的更多信息。我可以提供一些入门指针,但我很确定您会找到更多关于此类主题的指针。
