Hack and / - Lightning Hacks--SSH Strikes Back

作者:Kyle Rankin

我大约每年都会写一篇题为“Lightning Hacks”的专栏文章。这个专栏的灵感来自于大多数会议上常见的闪电演讲。在闪电演讲中,不是由一位演讲者进行 60 分钟的演讲,而是由多位演讲者进行 5-10 分钟的简短演讲。在一次闪电演讲结束时,您最终会听到各种各样的酷炫主题,这些主题本来不会有自己的时间段。在本专栏中,我将有机会谈论一些我偶然发现的酷炫“技巧”,这些技巧本身不足以写满整个专栏。

在之前的“Lightning Hacks”专栏中,我介绍了很多不同的主题,但这次我决定只关注一个主题:SSH。像许多系统管理员一样,我一天中的大部分时间都在 SSH 会话中度过,多年来,我发现了一些快捷方式和实用技巧,我将它们保存在 shell 脚本中,以免忘记。

自动加载类似 Screen 的会话

第一个技巧看起来非常简单——毕竟,我只是在 SSH 中添加了一个额外的标志。通常,如果您想ssh进入一台机器并运行程序,您只需在 SSH 命令的末尾传递程序即可

$ ssh user@remotehost.example.org df

但是,如果您曾经尝试编写一个 shell 脚本来自动ssh进入远程机器并启动 mutt 或 screen 或类似程序,您会看到会话要么停在那里,要么退出并显示类似“必须连接到终端”的消息。当我想在 N900 掌上电脑上启动两个特殊的终端会话时,我遇到了这个问题:一个自动重新连接到远程 screen 会话,另一个加载 mutt。是的,没错。即使在掌上电脑上,我仍然更喜欢 mutt 和 irssi。但在我添加 -t 标志之前,它们都无法工作

$ ssh -t user@remotehost.example.org screen -dr
$ ssh -t user@remotehost.example.org mutt

第一个示例连接到远程主机并重新连接我的远程 screen 会话(我在我的主机上只运行一个 screen 会话,然后使用 Ctrl-a c 在该会话中创建窗口)。第二个示例只是运行 mutt。-t 标志强制伪终端分配。事实证明,当您运行 screen 或 mutt 等程序时,您需要强制 SSH 创建一个伪终端。

绕过恼人的防火墙

我知道已经写过数百万篇关于 SSH 隧道的文章,但这种特殊的隧道非常有用;但是,我不经常使用它,而且会忘记正确的语法。您经常可能遇到的一个问题是需要scp在两台服务器(例如 londonweb1 和 seattleweb1)之间传输大量文件,但由于某种原因,这两台机器彼此之间被防火墙隔离了。通常,您有一台服务器能够ssh进入这两台机器(我们称之为 admin1),如果只需要传输一两个文件,您可以先将文件从 londonweb1 复制到 admin1,然后再从 admin1 复制到 seattleweb1。

当您需要在两个站点之间传输多个文件(或者可能通过管道传输 dd 流量)时,首先将数据移动到中间服务器可能是不切实际的,甚至是不可能的。这就是 SSH 反向隧道派上用场的地方。使用反向隧道,您可以从您的中间服务器(本例中为 admin1)启动到第一台服务器 (londonweb1) 的 SSH 会话,并打开一个未使用的本地高端口,例如 2222。然后,您告诉 SSH 将该端口上的所有流量隧道传输到远程服务器 (seattleweb1)。隧道设置好后,您可以像往常一样使用 scp,只需将其指向 localhost 端口 2222 即可。

要设置隧道,我将从 admin1 运行以下命令

kyle@admin1:~$ ssh -R 2222:seattleweb1:22 londonweb1

-R 的参数很容易混淆。请注意,命令中的最后一个服务器 (londonweb1) 是我登录的服务器。-R 的第一个参数是在该服务器上打开的端口 (2222)。接下来的两个参数列出了要将任何流量转发到的服务器和端口(分别为 seattleweb1 和 22)。

一旦我登录到 londonweb1,我就可以像往常一样使用 scp(或 rsync),但我将其指向 localhost 端口 2222

kyle@londonweb1:~$ scp -r -P 2222 /var/www/mysite localhost:/var/www/

当我启动此 scp 命令时,所有流量都进入隧道并到达 admin1,然后从那里转发到 seattleweb1 上的端口 22。请记住,这意味着如果这些机器相距很远,您的瓶颈将是服务器之间最慢的链路。

如果您是负责网络的安全意识人士,您可能不喜欢绕过基本防火墙规则的容易程度。重要的是要意识到,反向隧道也可以用于从您的网络内部连接到个人的家用机器,因此即使设置了传入防火墙规则,用户仍然可以隧道进入。

动态添加 SSH 隧道

SSH 的一个不太为人所知的功能是,您可以在现有会话中进入内部命令行模式并添加额外的隧道。假设您已经打开了从 admin1 到 londonweb1 的 SSH 会话,现在您想添加反向隧道而无需注销。首先,按 ~C(即 ~ 字符,然后是大写字母 C)打开 SSH 命令行。然后,您可以添加额外的端口转发命令,就像它们是原始 SSH 命令行的一部分一样。完成后,只需按 Enter 即可返回常规 shell

kyle@londonweb1:~$ 
ssh> -R 2222:seattleweb1:22
Forwarding port.

kyle@londonweb1:~$

如果您使用常规 SSH 隧道(-L 选项)作为简易 VPN,并意识到例如您需要为新服务器设置额外的 VNC 或 RDP 隧道,这也可能很有用。当您使用 SSH 命令行时,您不必关闭和中断您已有的任何现有会话。

Kyle Rankin 是旧金山湾区的系统架构师,也是许多本书的作者,包括 The Official Ubuntu Server BookKnoppix HacksUbuntu Hacks。他目前是北湾 Linux 用户组的主席。

加载 Disqus 评论