SSH 的 11 个技巧

作者:Daniel R. Allen

SSH 是 rsh 和 rlogin 的后代,rsh 和 rlogin 是用于远程 shell 登录的非加密程序。Rsh 和 rlogin,以及 telnet,都有很长的历史,但现在已经过时且不安全。然而,这些程序在 UNIX 开发的二十年中发展出了许多出色的功能,其中最好的功能被融入了 SSH。以下是我发现的 11 个技巧,可用于最大限度地发挥 SSH 的强大功能。

安装和版本

OpenSSH 是最常见的免费 SSH 版本,几乎适用于所有类 UNIX 操作系统。Debian、SuSE、Red Hat、Mandrake、Slackware、Caldera 和 Gentoo Linux,以及 OpenBSD、Windows 的 Cygwin 和 Mac OS X 默认都包含它。本文基于 OpenSSH,因此如果您使用的是其他版本,请在尝试这些技巧之前查看您的文档。

X11 转发

您可以通过 SSH 加密 X 会话。不仅流量被加密,而且远程系统上的 DISPLAY 环境变量也设置正确。因此,如果您在本地计算机上运行 X,您的远程 X 应用程序会神奇地出现在您的本地屏幕上。

使用以下命令打开 X11 转发ssh -X host。您应该仅对信任管理员的远程计算机使用 X11 转发。否则,您可能会受到基于 X11 的攻击。

使用 X11 转发的一个巧妙技巧是在 xterm 窗口中显示图像。在远程机器上运行带有内联图像扩展的网络浏览器 w3m;请参阅 Debian 软件包 w3m-img 或 RPM w3m-imgdisplay。它使用 X11 转发在您的 xterm 顶部打开一个无边框窗口。如果您使用 SSH 和基于文本的客户端远程读取电子邮件,则可以在同一个 xterm 窗口中显示内联图像。

配置文件

SSH 在 ~/.ssh/config 中查找用户配置文件。一个示例可能如下所示

ForwardX11 yes
Protocol 2,1

使用ForwardX11 yes与指定-X在命令行上相同。“Protocol”行告诉 SSH 首先尝试 SSH2,然后回退到 SSH1。如果您只想使用 SSH2,请删除,1.

配置文件可以包含仅对某些远程主机生效的部分,方法是使用 Host 选项。另一个有用的配置文件选项是 User,它指定远程用户名。如果您经常使用以下命令登录到机器ssh -l remoteuser remotehostssh remoteuser@remotehost,您可以通过在配置文件中放置以下行来缩短此操作

Host remotehost
ForwardX11 yes
User remoteuser

Host *
ForwardX11 no

现在,您可以输入ssh remotehost以用户 remoteuser 身份登录,并启用 ForwardX11 选项。否则,ForwardX11 将被关闭,如上所述推荐。星号匹配所有主机,包括 Host 部分中已匹配的主机,但仅使用第一个匹配的选项。将特定的 Host 部分放在配置文件中的通用部分之前。

系统范围的 SSH 配置文件 /etc/ssh/ssh_config 也可用。SSH 按以下顺序获取配置数据:命令行选项、用户配置文件和系统范围的配置文件。所有选项都可以通过浏览 man ssh_config 来探索。

加速:压缩和密码

SSH 可以在任何连接上使用 gzip 压缩。默认压缩级别相当于文本大约 4 倍的压缩率。如果您在拨号或慢速网络上转发 X 会话,则压缩是一个好主意。使用以下命令打开压缩ssh -C或放置Compression yes在您的配置文件中。

另一个速度调整涉及更改您的加密密码。许多旧系统上的默认密码是三重 DES (3DES),它比 Blowfish 和 AES 慢。新版本的 OpenSSH 默认使用 Blowfish。您可以使用以下命令将密码更改为 blowfishssh -c blowfish.

对配置文件的密码更改取决于您是使用 SSH1 还是 SSH2 连接。对于 SSH1,请使用Cipher blowfish;对于 SSH2,请使用

Ciphers blowfish-cbc,aes128-cbc,3des-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
端口转发

端口是表示服务器上不同服务的数字;例如,端口 80 用于 HTTP,端口 110 用于 POP3。您可以在 /etc/services 中找到标准端口号及其服务的列表。SSH 可以透明地转换从您的计算机上的任意端口到运行 SSH 的远程服务器的所有流量。然后,流量可以由 SSH 转发到另一台服务器上的任意端口。您为什么要这样做?两个原因:加密和隧道连接。

加密

许多应用程序使用协议,其中密码和数据以明文形式发送。这些协议包括 POP3、IMAP、SMTP 和 NNTP。SSH 可以透明地加密这些连接。假设您的电子邮件程序通常连接到 mail.example.net 上的 POP3 端口 (110)。另外,假设您无法直接 SSH 连接到 mail.example.net,但您在 shell.example.net 上有 shell 登录名。您可以指示 SSH 加密来自本地计算机上端口 9110(任意选择)的流量,并使用 shell.example.net 上的 SSH 服务器将其发送到 mail.example.net 上的端口 110

ssh -L 9110:mail.example.net:110 shell.example.net

也就是说,通过与 shell.example.net 的 SSH 连接,将本地端口 9110 发送到 mail.example.net 端口 110。

然后,只需告诉您的电子邮件程序连接到 localhost 上的端口 9110。从那里,数据被加密,通过 SSH 端口传输到 shell.example.net,然后解密并通过端口 110 传递到 mail.example.net。作为一个巧妙的副作用,就 mail.example.net 上的 POP3 守护程序而言,它正在接受来自 shell.example.net 的流量。

隧道连接

无论防火墙是保护您的计算机、远程服务器还是两者都保护,SSH 都可以充当通过防火墙的桥梁。您只需要一个暴露于防火墙另一侧的 SSH 服务器。例如,许多 DSL 和有线调制解调器公司禁止通过端口 25 (SMTP) 从您自己的机器发送电子邮件。

我们的下一个示例是通过您的有线调制解调器连接向您公司的 SMTP 服务器发送邮件。在本示例中,我们使用 SMTP 服务器上的 shell 帐户,该服务器名为 mail.example.net。SSH 命令是

ssh -L 9025:mail.example.net:25 mail.example.net

然后,告诉您的邮件传输代理连接到 localhost 上的端口 9025 以发送邮件。此练习应与上一个示例非常相似;我们正在通过 mail.example.net 将本地端口 9025 隧道传输到 mail.example.net 端口 25。就防火墙而言,它正在您和 mail.example.net 之间正常的 SSH 端口 22 上传递正常的 SSH 数据。

最后一个示例是通过 ISP 防火墙连接到受限网络内的邮件或新闻服务器。这会是什么样子?实际上,它与第一个示例相同;mail.example.net 可以被隔离在网络内部,外部世界无法访问。您只需要与可以看到它的服务器建立 SSH 连接,例如 shell.example.net。这不是很棒吗?

端口转发的限制/改进

如果在计算机上重新分配了端口(上述示例中的本地端口),则该计算机的每个用户都会看到重新分配的端口。如果本地系统有多个用户,则仅从未使用的、编号较高的端口进行隧道传输,以避免混淆。如果您想转发特权本地端口(低于 1024),则需要以 root 用户身份执行此操作。如果程序不允许您更改其端口,例如标准 BSD FTP,则转发较低编号的端口可能很有用。

默认情况下,隧道本地端口仅本地用户可访问,而远程连接不可访问。但是,任何用户都可以使用 -g 选项使隧道端口远程可用。同样,只有当您是 root 用户时,才能对特权端口执行此操作。

任何可以使用 SSH 登录的用户都可以使用端口转发将专用网络内的任何端口暴露给外部世界。作为管理员,如果您允许传入的 SSH 连接,您实际上是在允许任何类型的传入连接。您可以配置 OpenSSH 守护程序以拒绝端口转发,方法是AllowTcpForwarding no,但坚定的用户仍然可以转发。

配置文件选项可用于转发端口;它被称为 LocalForward。上面给出的第一个端口转发示例可以写成

Host forwardpop
Hostname shell.example.com
LocalForward 9110 mail.example.com:110

这样,如果您输入ssh forwardpop您将收到与第一个示例相同的结果。此示例使用了上面描述的 Host 命令和 HostName 命令,该命令指定要连接的真实主机名。

最后,一个类似于 LocalForward 的命令,称为 RemoteForward,将端口从您连接的计算机转发到您的计算机。请阅读 ssh_config 手册页以了解如何操作。

将二进制数据管道传输到远程 Shell

管道通过 SSH 透明地工作到远程 shell。考虑

cat myfile | ssh user@desktop lpr

tar -cf - source_dir | \
ssh user@desktop 'cat > dest.tar'

第一个示例将 myfile 管道传输到在名为 desktop 的机器上运行的 lpr。第二个示例创建一个 tar 文件并将其写入终端(因为 tar 文件名指定为破折号),然后将其管道传输到名为 desktop 的机器并重定向到文件。

运行远程 Shell 命令

使用 SSH,如果您只想从远程命令获取一些输出,则无需打开交互式 shell,例如

ssh user@host w

此命令以用户身份在主机上运行命令 w 并显示结果。它可以用于自动化命令,例如

perl -e 'foreach $i (1 .. 12) \
{print `ssh server$i "w"`}'

请注意 SSH 命令周围的反引号。这使用 Perl 调用 SSH 12 次,每次在不同的远程主机 server1 到 server12 上运行命令 w。此外,您每次 SSH 建立连接时都需要输入密码。但是,请继续阅读以了解如何在不牺牲安全性的情况下消除密码要求。

身份验证

SSH 如何验证您是否应该被允许连接?以下是一些选项

  • 仅通过主机名:使用 .rhosts 文件;不安全;默认禁用。

  • 通过主机名和主机密钥检查。

  • S/Key 一次性密码系统。

  • Kerberos:使用有时效的“票证”的私钥加密。

  • 智能卡。

  • 密码提示。

  • 公钥。

最常见的身份验证方法是通过密码提示,这是大多数 SSH 安装开箱即用的方式。

但是,公钥加密值得研究;它比密码安全得多,并且通过使用它,您可以免除所有或大部分密码输入。

简而言之,公钥加密依赖于两个密钥:用于加密的公钥(您不必保密)和用于解密的私钥(在您的本地计算机上保密)。一般思路是运行ssh-keygen以生成您的密钥。当它要求您输入密码短语时,按回车键。然后将您的公钥复制到远程计算机的 authorized_keys 文件中。

详细信息取决于您连接的计算机是使用 SSH1 还是 SSH2。对于 SSH1,输入ssh-keygen -t rsa1,并将 ~/.ssh/identity.pub 复制到远程计算机上 ~/.ssh/authorized_keys 文件的末尾。对于 SSH2,输入ssh-keygen -t rsa,并将 ~/.ssh/id_rsa.pub 复制到远程计算机上 ~/.ssh/authorized_keys 文件的末尾。此文件可能称为 ~/.ssh/authorized_keys2,具体取决于您的 OpenSSH 版本。如果第一个不起作用,请尝试第二个。这样做的好处是您可以无需输入密码即可登录。

您可以使用密码短语来保护您本地计算机上的私钥。密码短语使用 3DES 加密私钥。在任何时候,您的密码短语或任何秘密信息都不会通过网络发送。当您连接到远程计算机时,您仍然需要输入密码短语。

身份验证代理

您可能想知道:如果我们想使用密码短语,我们是否又回到了起点,每次登录都要输入密码短语?不。相反,您可以使用密码短语,但只需输入一次,而不是每次使用私钥时都输入。要设置此密码短语,请执行ssh-agent当您首次启动会话时。然后执行ssh-add,它会提示您输入密码短语并将其存储在内存中,而不是磁盘上。从那时起,所有使用您的私钥进行身份验证的连接都将使用内存中的版本,并且不会要求您输入密码。

您的发行版可能设置为在您启动 X 时启动 ssh-agent。要查看它是否已在运行,请输入ssh-add -L。如果代理尚未运行,则需要启动它,您可以通过将其添加到您的 .bash_login 中,注销并重新登录来完成。

身份验证代理转发

如果您使用公钥身份验证从一台服务器连接到另一台服务器,则无需在两台服务器上都运行身份验证代理。SSH 可以自动将来自其他服务器的所有身份验证请求传递回您自己的计算机上运行的代理。这样,它永远不会将您的密钥泄露给远程计算机;相反,它在您的计算机上执行身份验证并将结果发送回远程计算机。

要设置身份验证代理转发,只需运行ssh -A或将以下行添加到您的配置文件中

ForwardAgent yes

您应该仅在信任远程计算机的管理员的情况下使用身份验证代理转发;您冒着他们像您一样使用您的密钥的风险。否则,它是非常安全的。

使用 SSH Java Applet 旅行

许多人携带一张装有 PuTTY 或其他 Windows SSH 程序的软盘,以防他们在旅行时需要使用不安全的计算机。如果您有能力从软盘驱动器运行程序,则此方法有效。您也可以从网站下载 PuTTY 并运行它。

另一种选择是将 SSH Java applet 放在您可以从浏览器使用的网页上。一个优秀的 Java SSH 客户端是 Mindterm,它对于非商业用途是免费的。您可以在 www.appgate.com/mindterm 找到它。

结论

如果您正在使用这些各种技巧,SSH 配置可能会在几个地方出错。您可以使用ssh -v并观看输出来捕获许多问题。当然,这些技巧对于使用 SSH 来说都不是必需的。但是,最终,您可能会遇到您很高兴知道它们的 ситуации。所以尝试其中的一些技巧吧。

Daniel R. Allen (da@coder.com) 在 MIT 体验了 UNIX 的魅力,这得益于一个 1200 波特的调制解调器、一个免费的本地拨号和一个访客帐户,那时这些东西还存在。自 1995 年以来,他一直是热情的 Linux 用户。他是 Prescient Code Solutions 的总裁,Prescient Code Solutions 是一家位于安大略省基奇纳和纽约州伊萨卡的软件咨询公司。

加载 Disqus 评论