前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
介绍
SSH,即Secure Shell,是连接到 Linux 服务器进行远程管理的最常见方式。虽然通过命令行连接到单个服务器相对简单,但对于连接到多个远程系统,有许多工作流程优化。
OpenSSH 是大多数系统上最常用的命令行 SSH 客户端,它允许您提供自定义的连接选项。这些选项可以保存到包含不同选项的配置文件中。这有助于保持您为每个主机使用的不同连接选项分离和组织,并避免在每次需要连接时在命令行上提供广泛的选项。
在本指南中,我们将介绍 SSH 客户端配置文件的结构,并介绍一些常见选项。
先决条件
要完成本指南,您需要对 SSH 以及连接时可以提供的一些选项有一定了解。您还应该为一些用户或服务器配置基于 SSH 密钥的身份验证,至少用于测试目的。
SSH 配置文件结构和解释算法
系统上的每个用户都可以在其主目录中维护自己的 SSH 配置文件。这些文件可以包含您在命令行上使用的任何选项,以指定连接参数。始终可以通过在 ssh
命令中添加额外的标志来覆盖配置文件中定义的值。
SSH 客户端配置文件的位置
客户端配置文件位于 ~/.ssh/config
– ~
是指主目录的通用快捷方式。通常,此文件不会自动创建,因此您可能需要自己创建它。如果文件不存在,touch
命令将创建它(如果存在,则更新最后修改的时间戳)。
touch ~/.ssh/config
配置文件结构
config
文件按主机组织,即按远程服务器组织。每个主机定义可以为特定匹配主机定义连接选项。通配符也支持应具有更广泛范围的选项。
每个部分以定义匹配配置选项的主机的标题开头。然后在下面定义了该匹配主机的特定配置项。只需要指定与默认值不同的项目,因为每个条目将继承未定义项目的默认值。每个部分从一个 Host
标头延伸到下一个 Host
标头。
通常,出于组织目的和可读性,为每个主机设置的选项会缩进。这不是硬性要求,但是一个有用的约定,可以让您一目了然地解释。
一般格式如下:
Host firsthost
Hostname your-server.com
User username-to-connect-as
IdentityFile /path/to/non/default/keys.pem
Host secondhost
ANOTHER_OPTION custom_value
Host *host
ANOTHER_OPTION custom_value
Host *
CHANGE_DEFAULT custom_value
在这里,我们有四个部分,将根据主机是否匹配在每次连接尝试中应用。
解释算法
了解 SSH 如何解释文件以应用配置值很重要。这在使用通配符和 Host *
通用主机定义时有影响。
SSH 将命令行提供的主机名与定义配置部分的每个 Host
标头进行匹配。
例如,考虑以下定义:
Host devel
HostName devel.example.com
User tom
此主机允许我们通过在命令行上键入以下内容连接为 tom@devel.example.com
:
ssh devel
SSH 从配置文件顶部开始,检查每个 Host
定义,看它是否与命令行中给定的值匹配。找到第一个匹配的 Host
定义后,将应用与即将到来的连接相关联的每个关联的 SSH 选项。
然后,SSH 向下移动文件,检查其他 Host
定义是否也匹配。如果找到另一个匹配当前命令行中给定主机名的定义,它将考虑新部分的关联 SSH 选项。然后将应用任何先前部分未定义的新部分定义的 SSH 选项。
这是一个重要的观点。SSH 将按顺序解释与命令行中给定主机名匹配的每个 Host
部分。在此过程中,它将始终使用每个选项的第一个给定值。无法覆盖先前匹配部分给出的值。
这意味着您的 config
文件应遵循在顶部具有最具体配置的规则。更一般的定义应该稍后出现,以应用先前匹配部分未定义的选项。
让我们再次看一下上一节中的示例:
Host firsthost
Hostname your-server.com
User username-to-connect-as
IdentityFile /path/to/non/default/keys.pem
Host secondhost
ANOTHER_OPTION custom_value
Host *host
ANOTHER_OPTION custom_value
Host *
CHANGE_DEFAULT custom_value
在这里,我们可以看到前两个部分由文字主机名(或别名)定义,这意味着它们不使用任何通配符。如果我们使用 ssh firsthost
进行连接,将首先应用第一部分。这将为此连接设置 Hostname
、User
和 IdentityFile
。
它将检查第二部分,发现它不匹配,然后继续。然后找到第三部分并发现它匹配。它将检查 ANOTHER_OPTION
,看它是否已经有了来自先前部分的值。发现它没有,它将应用此部分的值。然后将匹配最后一部分,因为 Host *
定义匹配每个连接。由于它没有来自其他部分的虚拟 CHANGE_DEFAULT
选项的值,它将采用此部分的值。然后使用从此过程中收集的选项进行连接。
让我们再试一次,假装从命令行调用 ssh secondhost
。
同样,它将从第一部分开始,并检查是否匹配。由于这只匹配到 firsthost
的连接,因此将跳过此部分。然后移动到第二部分。在发现此部分匹配请求后,将收集此连接的 ANOTHER_OPTION
值。
然后,SSH 查看第三个定义,并发现通配符匹配当前连接。然后检查是否已经有了 ANOTHER_OPTION
的值。由于此选项在已匹配的第二部分中定义,因此第三部分的值被丢弃并且没有效果。
SSH 然后检查第四部分,并应用尚未由先前匹配部分定义的选项。然后尝试使用收集到的值进行连接。
连接选项
现在你已经了解了如何编写配置文件,让我们讨论一些常见选项以及在命令行中指定它们的格式。
我们首先要讨论的是连接到远程主机所需的最小设置。即,SSH 服务器运行的主机名、用户名和端口。
要从命令行连接到一个名为 example.com
的主机,该主机的 SSH 守护程序运行在端口 4567
上,用户名为 apollo
,你可以这样运行 ssh
:
ssh -p 4567 apollo@example.com
但是,你也可以使用完整的选项名称和 -o
标志,就像这样:
ssh -o "User=apollo" -o "Port=4567" -o "HostName=example.com"
你可以在 SSH 手册页中找到所有可用选项的完整列表。
要在你的 config
文件中设置这些选项,你必须选择一个 Host
标头名称,比如 home
:
Host home
HostName example.com
User apollo
Port 4567
常见 SSH 配置选项
到目前为止,我们已经讨论了一些建立连接所需的选项。我们已经涵盖了这些选项:
- HostName:用于建立连接的实际主机名。这将替换
Host
标头中定义的任何别名。如果Host
定义指定了实际的有效地址以连接到,则此选项是不必要的。 - User:用于连接的用户名。
- Port:远程 SSH 守护程序运行的端口。如果远程 SSH 实例未运行在默认端口
22
上,则此选项是必要的。
还有许多其他有用的选项值得探索。我们将根据功能将一些常见选项进行讨论。
一般调整和连接项目
-
ServerAliveInterval
:此选项可配置 SSH 何时发送数据包以测试服务器的响应。如果你的连接不稳定,并且想知道它是否仍然可用,这可能会很有用。 -
LogLevel
:配置 SSH 在客户端记录详细程度。这可用于在某些情况下关闭日志记录或在调试时增加详细程度。从最不详细到最详细,级别为 QUIET、FATAL、ERROR、INFO、VERBOSE、DEBUG1、DEBUG2 和 DEBUG3。 -
StrictHostKeyChecking
:此选项配置 SSH 是否会自动将主机添加到~/.ssh/known_hosts
文件。默认情况下,此选项将设置为 “ask”,这意味着如果从远程服务器接收到的主机密钥与known_hosts
文件中找到的密钥不匹配,它将向你发出警告。如果你经常连接大量的临时主机(例如测试服务器),你可能希望将其设置为 “no”。SSH 将自动将任何主机添加到该文件中。如果你的已知主机地址在不应该更改的情况下发生更改,这可能会带来安全隐患,因此在启用之前请仔细考虑。 -
UserKnownHostsFile
:此选项指定 SSH 将存储已连接到的主机信息的位置。通常情况下,你不必担心此设置,但如果你已关闭了严格的主机检查,你可能希望将其设置为/dev/null
以便丢弃这些信息。 -
VisualHostKey
:此选项可告诉 SSH 在连接时显示远程主机密钥的 ASCII 表示。打开此选项可以帮助你熟悉主机密钥,以便在将来必须从不同计算机连接时能够识别它。 -
Compression
:打开压缩对于非常慢的连接可能会有所帮助。大多数用户不需要此选项。
有了上述配置项目,我们可以进行许多有用的配置调整。
例如,如果我们在云提供商快速创建和销毁主机,可能会有用的是这样的配置:
Host home
VisualHostKey yes
Host cloud*
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
LogLevel QUIET
Host *
StrictHostKeyChecking ask
UserKnownHostsFile ~/.ssh/known_hosts
LogLevel INFO
ServerAliveInterval 120
这将为你的 home 连接打开可视化主机密钥,让你熟悉它,以便在它发生变化或从不同的计算机连接时能够识别它。我们还设置了任何以 cloud* 开头的主机不检查主机并且不记录失败。对于其他主机,我们有合理的回退值。
连接转发
SSH 的一个常见用途是转发连接,允许本地连接通过远程主机进行隧道传输,或者允许远程机器通过本地机器进行隧道传输。当你需要通过一个单独的指定“网关”服务器连接到防火墙后面的远程机器时,这有时是必要的。SSH 还可以使用像 SOCKS5 这样的协议进行动态转发。
控制此行为的选项包括:
-
LocalForward
:此选项用于指定将本地端口的流量转发到远程机器,将其隧道传输到远程网络。第一个参数应该是你希望将流量定向到的本地端口,第二个参数应该是你希望在远程端点上将该流量定向到的地址和端口。 -
RemoteForward
:此选项用于定义可以将流量定向到以便从本地机器进行隧道传输的远程端口。第一个参数应该是远程系统上流量将被定向到的远程端口。第二个参数应该是当它到达本地系统时要将流量指向的地址和端口。 -
DynamicForward
:这用于配置可以与像 SOCKS5 这样的动态转发协议一起使用的本地端口。使用动态转发协议的流量可以在本地机器上定向到此端口,在远程端点上,它将根据包含的值进行路由。
这些选项可以用于双向转发端口,如下所示:
这将允许我们在本地机器上使用端口8080
以便从远程机器访问 example.com 的80端口
Host local_to_remote
LocalForward 8080 example.com:80
这将允许我们通过另一侧的7777端口
向远程机器提供对 internal.com 的443端口的访问
Host remote_to_local
RemoteForward 7777 internal.com:443
当您需要打开浏览器窗口访问在不直接通过 SSH 访问的服务器上运行的私有仪表板或其他 Web 应用程序时,这将非常有用。
### 其他转发
除了连接转发,SSH 还允许其他类型的转发。
您可以转发存储在本地机器上代理中的任何 SSH 密钥,从而允许我们使用存储在本地系统上的凭据连接到远程系统。您还可以在远程系统上启动应用程序,并使用 X11 转发将图形显示到本地系统。X11 是 Linux 显示服务器,如果您同时使用远程和本地 Linux 环境,它可能不太直观,但非常有用。
以下是与这些功能相关联的指令:
* **`ForwardAgent`**:此选项允许将存储在本地机器上的身份验证密钥转发到您要连接的系统。这可以让您使用您的家庭密钥从主机到主机跳转。
* **`ForwardX11`**:如果您希望能够转发在远程系统上运行的应用程序的图形屏幕,可以打开此选项。
### 指定密钥
如果为您的主机配置了 SSH 密钥,这些选项可以帮助您管理每个主机使用的密钥。
* **`IdentityFile`**:此选项可用于指定每个主机使用的密钥的位置。SSH 默认将使用位于 `~/.ssh` 中的密钥,但如果您为每个服务器分配了密钥,则可以使用此选项指定它们的确切路径。
* **`IdentitiesOnly`**:此选项可用于强制 SSH 仅依赖于 `config` 文件中提供的标识。如果 SSH 代理在内存中具有不适用于所讨论的主机的备用密钥,则可能需要使用此选项。
如果您必须跟踪不同主机的大量密钥并使用一个或多个 SSH 代理来协助,这些选项尤其有用。
## 结论
只要您牢记 SSH 将如何解释这些值,您就可以建立具有合理回退的特定值的丰富集合。
如果您必须在非常差或间歇性的连接(例如飞机上的 Wi-Fi)上使用 SSH,您还可以尝试使用 mosh,它旨在使 SSH 在不利情况下工作。