SSHEssentials:使用SSH服务器、客户端和密钥

来自菜鸟教程
跳转至:导航、​搜索

介绍

SSH 是一种安全协议,用作远程连接到 Linux 服务器的主要方式。 它通过生成远程 shell 来提供基于文本的界面。 连接后,您在本地终端中键入的所有命令都会发送到远程服务器并在那里执行。

在本备忘单式指南中,我们将介绍一些使用 SSH 连接以实现目标的常用方法。 当您需要了解如何以不同方式连接或配置您的服务器时,这可以用作快速参考。

如何使用本指南

  • 如果您不熟悉 SSH 或刚刚开始使用,请先阅读 SSH 概述部分
  • 使用适用于您要达到的目标的任何后续部分。 大多数部分不以任何其他部分为基础,因此您可以独立使用以下示例。
  • 使用此页面左侧的目录菜单(宽页面宽度)或浏览器的查找功能找到您需要的部分。
  • 复制并粘贴给出的命令行示例,将 highlighted 值替换为您自己的值。

SSH 概述

连接到远程 Linux 服务器的最常见方式是通过 SSH。 SSH 代表 Secure Shell,它提供了一种安全可靠的方式来远程执行命令、进行更改和配置服务。 通过 SSH 连接时,您使用远程服务器上存在的帐户登录。

SSH 的工作原理

当您通过 SSH 连接时,您将进入一个 shell 会话,这是一个基于文本的界面,您可以在其中与您的服务器进行交互。 在 SSH 会话期间,您在本地终端中键入的任何命令都将通过加密的 SSH 隧道发送并在您的服务器上执行。

SSH 连接是使用客户端-服务器模型实现的。 这意味着要建立 SSH 连接,远程计算机必须运行一个称为 SSH 守护程序的软件。 该软件侦听特定网络端口上的连接,验证连接请求,并在用户提供正确凭据时生成适当的环境。

用户的计算机必须有 SSH 客户端。 这是一款知道如何使用 SSH 协议进行通信的软件,并且可以提供有关要连接的远程主机、要使用的用户名以及应传递以进行身份验证的凭据的信息。 客户端还可以指定有关他们想要建立的连接类型的某些详细信息。

SSH 如何对用户进行身份验证

客户端通常使用密码(不太安全且不推荐)或非常安全的 SSH 密钥进行身份验证。

密码登录是加密的,新用户很容易理解。 但是,自动机器人和恶意用户通常会反复尝试对允许基于密码登录的帐户进行身份验证,这可能会导致安全隐患。 因此,我们建议始终为大多数配置设置基于 SSH 密钥的身份验证。

SSH 密钥是一组匹配的加密密钥,可用于身份验证。 每个集合都包含一个公钥和一个私钥。 公钥可以无忧无虑地自由共享,而私钥必须受到严密保护,绝不能暴露给任何人。

要使用 SSH 密钥进行身份验证,用户的本地计算机上必须有一个 SSH 密钥对。 在远程服务器上,必须将公钥复制到用户主目录 ~/.ssh/authorized_keys 中的文件中。 此文件包含一个公钥列表,每行一个,被授权登录该帐户。

当客户端连接到主机时,希望使用 SSH 密钥身份验证,它将通知服务器此意图并告诉服务器使用哪个公钥。 然后服务器检查其 authorized_keys 文件中的公钥,生成随机字符串,并使用公钥对其进行加密。 此加密消息只能使用关联的私钥解密。 服务器会将此加密消息发送给客户端,以测试他们是否真的拥有相关的私钥。

收到此消息后,客户端将使用私钥对其进行解密,并将显示的随机字符串与先前协商的会话 ID 结合起来。 然后,它会生成该值的 MD5 散列并将其传输回服务器。 服务器已经拥有原始消息和会话 ID,因此它可以比较由这些值生成的 MD5 哈希,并确定客户端必须拥有私钥。

现在您知道 SSH 是如何工作的,我们可以开始讨论一些示例来演示使用 SSH 的不同方式

生成和使用 SSH 密钥

本节将介绍如何在客户端计算机上生成 SSH 密钥并将公钥分发到应该使用它们的服务器。 如果您以前没有生成密钥,这是一个很好的开始部分,因为它允许未来连接增加了安全性。

生成 SSH 密钥对

在您的本地计算机上生成一个新的 SSH 公钥和私钥对是在没有密码的情况下使用远程服务器进行身份验证的第一步。 除非有充分的理由不这样做,否则您应该始终使用 SSH 密钥进行身份验证。

许多加密算法可用于生成 SSH 密钥,包括 RSA、DSA 和 ECDSA。 RSA 密钥通常是首选并且是默认密钥类型。

要在本地计算机上生成 RSA 密钥对,请键入:

ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/demo/.ssh/id_rsa):

此提示允许您选择存储 RSA 私钥的位置。 按 ENTER 将其保留为默认值,这会将它们存储在用户主目录的 .ssh 隐藏目录中。 选择默认位置将允许您的 SSH 客户端自动找到密钥。

Enter passphrase (empty for no passphrase):
Enter same passphrase again:

下一个提示允许您输入任意长度的密码来保护您的私钥。 默认情况下,您每次使用私钥时都必须输入您在此处设置的任何密码,作为额外的安全措施。 如果您不想要密码,请随意按 ENTER 将此留空。 请记住,这将允许任何控制您的私钥的人登录您的服务器。

如果您选择输入密码,则在您键入时不会显示任何内容。 这是一个安全预防措施。

OutputYour identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
8c:e9:7c:fa:bf:c4:e5:9c:c9:b8:60:1f:fe:1c:d3:8a root@here
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|                 |
|                 |
|       +         |
|      o S   .    |
|     o   . * +   |
|      o + = O .  |
|       + = = +   |
|      ....Eo+    |
+-----------------+

此过程生成了一个 RSA SSH 密钥对,位于用户主目录的 .ssh 隐藏目录中。 这些文件是:

  • ~/.ssh/id_rsa:私钥。 不要分享这个文件!
  • ~/.ssh/id_rsa.pub:关联的公钥。 这可以免费共享而不会产生任何后果。

生成具有更多位数的 SSH 密钥对

SSH 密钥默认为 2048 位。 这通常被认为足以保证安全性,但您可以为更强化的密钥指定更多位数。

为此,请在 -b 参数中包含您想要的位数。 大多数服务器支持长度至少为 4096 位的密钥。 出于 DDOS 保护目的,可能不接受更长的密钥:

ssh-keygen -b 4096

如果您之前创建了不同的密钥,系统会询问您是否要覆盖以前的密钥:

Overwrite (y/n)?

如果您选择“是”,您之前的密钥将被覆盖,您将无法再使用该密钥登录服务器。 因此,请务必小心覆盖密钥。

删除或更改私钥上的密码

如果您为您的私钥生成了密码并希望更改或删除它,您可以轻松完成。

注意:要更改或删除密码,您必须知道原始密码。 如果您丢失了密钥的密码,则没有追索权,您将不得不生成一个新的密钥对。


要更改或删除密码,只需键入:

ssh-keygen -p
Enter file in which the key is (/root/.ssh/id_rsa):

您可以键入要修改的键的位置或按 ENTER 接受默认值:

Enter old passphrase:

输入您要更改的旧密码。 然后将提示您输入新密码:

Enter new passphrase (empty for no passphrase):
Enter same passphrase again:

在这里,输入您的新密码或按 ENTER 删除密码。

显示 SSH 密钥指纹

每个 SSH 密钥对共享一个加密“指纹”,可用于唯一标识密钥。 这在各种情况下都很有用。

要找出 SSH 密钥的指纹,请键入:

ssh-keygen -l
Enter file in which the key is (/root/.ssh/id_rsa):

如果键的位置正确,您可以按 ENTER,否则输入修改后的位置。 您将获得一个字符串,其中包含密钥的位长、指纹、为其创建的帐户和主机,以及使用的算法:

Output4096 8e:c4:82:47:87:c2:26:4b:68:ff:96:1a:39:62:9e:4e  demo@test (RSA)

使用 SSH-Copy-ID 将公共 SSH 密钥复制到服务器

要将您的公钥复制到服务器,允许您在没有密码的情况下进行身份验证,可以采用多种方法。

如果您当前为您的服务器配置了基于密码的 SSH 访问,并且您安装了 ssh-copy-id 实用程序,那么这是一个简单的过程。 ssh-copy-id 工具包含在许多 Linux 发行版的 OpenSSH 软件包中,因此很可能会默认安装它。

如果您有此选项,您可以通过键入以下内容轻松传输您的公钥:

ssh-copy-id username@remote_host

这将提示您输入远程系统上的用户帐户密码:

The authenticity of host '111.111.11.111 (111.111.11.111)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
demo@111.111.11.111's password:

输入密码后,您的 ~/.ssh/id_rsa.pub 密钥的内容将附加到用户帐户的 ~/.ssh/authorized_keys 文件的末尾:

OutputNumber of key(s) added: 1

Now try logging into the machine, with:   "ssh 'demo@111.111.11.111'"
and check to make sure that only the key(s) you wanted were added.

您现在可以在没有密码的情况下登录该帐户:

ssh username@remote_host

将您的公共 SSH 密钥复制到没有 SSH-Copy-ID 的服务器

如果您没有可用的 ssh-copy-id 实用程序,但仍具有对远程服务器的基于密码的 SSH 访问权限,则可以以不同的方式复制公钥的内容。

您可以输出密钥的内容并将其传送到 ssh 命令中。 在远程端,您可以确保 ~/.ssh 目录存在,然后将管道内容附加到 ~/.ssh/authorized_keys 文件中:

cat ~/.ssh/id_rsa.pub | ssh username@remote_host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

系统将要求您提供远程帐户的密码:

The authenticity of host '111.111.11.111 (111.111.11.111)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes
demo@111.111.11.111's password:

输入密码后,您的密钥将被复制,让您无需密码即可登录:

ssh username@remote_IP_host

手动将公共 SSH 密钥复制到服务器

如果您没有可用的基于密码的 SSH 访问,则必须手动将您的公钥添加到远程服务器。

在您的本地机器上,您可以通过键入以下命令找到您的公钥文件的内容:

cat ~/.ssh/id_rsa.pub
Outputssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCqql6MzstZYh1TmWWv11q5O3pISj2ZFl9HgH1JLknLLx44+tXfJ7mIrKNxOOwxIxvcBF8PXSYvobFYEZjGIVCEAjrUzLiIxbyCoxVyle7Q+bqgZ8SeeM8wzytsY+dVGcBxF6N4JS+zVk5eMcV385gG3Y6ON3EG112n6d+SMXY0OEBIcO6x+PnUSGHrSgpBgX7Ks1r7xqFa7heJLLt2wWwkARptX7udSq05paBhcpB0pHtA1Rfz3K2B+ZVIpSDfki9UVKzT8JUmwW6NNzSgxUfQHGwnW7kj4jp4AT0VZk3ADw497M2G/12N0PPB5CnhHf7ovgy6nL1ikrygTKRFmNZISvAcywB9GVqNAVE+ZHDSCuURNsAInVzgYo9xgJDW8wUw2o8U77+xiFxgI5QSZX3Iq7YLMgeksaO4rBJEa54k8m5wEiEE1nUhLuJ0X/vh2xPff6SQ1BL/zkOhvJCACK6Vb15mDOeCSq54Cr7kvS46itMosi/uS66+PujOO+xt/2FWYepz6ZlN70bRly57Q06J+ZJoc9FfBCbCyYH7U/ASsmY095ywPsBo1XQ9PqhnN1/YOorJ068foQDNVpm146mUpILVxmq41Cj55YKHEazXGsdBIbXWhcrRf4G2fJLRcGUr9q8/lERo9oxRm5JFX6TCmj6kmiFqv+Ow9gI0x8GvaQ== demo@test

您可以复制此值,然后手动将其粘贴到远程服务器上的适当位置。 您必须通过其他方式(如 DigitalOcean Web 控制台)登录到远程服务器。

在远程服务器上,如果 ~/.ssh 目录不存在,则创建它:

mkdir -p ~/.ssh

之后,您可以通过键入以下内容来创建或附加 ~/.ssh/authorized_keys 文件:

echo public_key_string >> ~/.ssh/authorized_keys

您现在应该能够在没有密码的情况下登录到远程服务器。

基本连接说明

以下部分将介绍有关如何使用 SSH 连接到服务器的一些基础知识。

连接到远程服务器

要连接到远程服务器并在那里打开 shell 会话,您可以使用 ssh 命令。

最简单的形式假定您在本地计算机上的用户名与远程服务器上的用户名相同。 如果这是真的,您可以使用以下方式进行连接:

ssh remote_host

如果您的用户名在远程服务器上不同,您需要像这样传递远程用户的名称:

ssh username@remote_host

您第一次连接到新主机时,您将看到如下所示的消息:

The authenticity of host '111.111.11.111 (111.111.11.111)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes

输入 yes 接受远程主机的真实性。

如果您使用密码验证,系统将提示您在此处输入远程帐户的密码。 如果您使用 SSH 密钥,如果设置了私钥,系统将提示您输入私钥的密码,否则您将自动登录。

在远程服务器上运行单个命令

要在远程服务器上运行单个命令而不是生成 shell 会话,您可以在连接信息之后添加命令,如下所示:

ssh username@remote_host command_to_run

这将连接到远程主机,使用您的凭据进行身份验证,并执行您指定的命令。 之后连接将立即关闭。

使用不同端口登录服务器

默认情况下,服务器上的 SSH 守护程序在端口 22 上运行。 您的 SSH 客户端将假定在尝试连接时就是这种情况。 如果您的 SSH 服务器正在侦听非标准端口(这将在后面的部分中演示),则在与客户端连接时必须指定新的端口号。

您可以通过使用 -p 选项指定端口号来执行此操作:

ssh -p port_num username@remote_host

为避免每次登录远程服务器时都必须这样做,您可以在本地计算机主目录的 ~/.ssh 目录中创建或编辑配置文件。

现在通过键入以下内容编辑或创建文件:

nano ~/.ssh/config

在这里,您可以设置特定于主机的配置选项。 要指定新端口,请使用如下格式:

~/.ssh/config

Host remote_alias
    HostName remote_host
    Port port_num

这将允许您登录而无需在命令行上指定特定端口号。

将 SSH 密钥添加到 SSH 代理以避免输入密码

如果您的私人 SSH 密钥上有密码,每次使用它连接到远程主机时,系统都会提示您输入密码。

为避免重复执行此操作,您可以运行 SSH 代理。 在您第一次输入密码后,这个小实用程序会存储您的私钥。 它将在您的终端会话期间可用,允许您将来连接而无需重新输入密码。

如果您需要转发 SSH 凭据(稍后显示),这也很重要。

要启动 SSH 代理,请在本地终端会话中键入以下内容:

eval $(ssh-agent)
OutputAgent pid 10891

这将启动代理程序并将其置于后台。 现在,您需要将您的私钥添加到代理,以便它可以管理您的密钥:

ssh-add
Enter passphrase for /home/demo/.ssh/id_rsa:
Identity added: /home/demo/.ssh/id_rsa (/home/demo/.ssh/id_rsa)

您必须输入密码(如果已设置)。 之后,您的身份文件将添加到代理中,允许您使用您的密钥登录,而无需再次重新输入密码。

转发您的 SSH 凭据以在服务器上使用

如果您希望无需密码即可从另一台服务器中连接到一台服务器,则需要转发您的 SSH 密钥信息。 这将允许您使用本地计算机上的凭据通过您连接到的服务器对另一台服务器进行身份验证。

首先,您必须启动 SSH 代理并将您的 SSH 密钥添加到代理(参见前面)。 完成此操作后,您需要使用 -A 选项连接到您的第一台服务器。 这会将您的凭据转发到此会话的服务器:

ssh -A username@remote_host

从这里,您可以通过 SSH 连接到您的 SSH 密钥有权访问的任何其他主机。 您将连接,就好像您的私人 SSH 密钥位于此服务器上一样。

服务器端配置选项

本节包含一些常见的服务器端配置选项,这些选项可以塑造您的服务器响应方式以及允许的连接类型。

禁用密码验证

如果您已配置、测试并正常工作的 SSH 密钥,那么禁用密码身份验证可能是个好主意。 这将阻止任何用户使用密码通过 SSH 登录。

为此,请连接到远程服务器并使用 root 或 sudo 权限打开 /etc/ssh/sshd_config 文件:

sudo nano /etc/ssh/sshd_config

在文件内部,搜索 PasswordAuthentication 指令。 如果已注释掉,请取消注释。 将其设置为 no 以禁用密码登录:

/etc/ssh/sshd_config

PasswordAuthentication no

进行更改后,保存并关闭文件。 要实施更改,您应该重新启动 SSH 服务。

在 Ubuntu/Debian 上:

sudo service ssh restart

在 CentOS/Fedora 上:

sudo service sshd restart

现在,系统上的所有帐户都将无法使用密码通过 SSH 登录。

更改 SSH 守护程序运行的端口

一些管理员建议您更改运行 SSH 的默认端口。 这可以帮助减少您的服务器受到自动机器人程序的身份验证尝试次数。

要更改 SSH 守护程序侦听的端口,您必须登录到远程服务器。 通过使用该用户登录或使用 sudo 以 root 权限打开远程系统上的 sshd_config 文件:

sudo nano /etc/ssh/sshd_config

进入后,您可以通过查找 Port 22 规范并修改它以反映您希望使用的端口来更改 SSH 运行的端口。 例如,要将端口更改为 4444,请将其放入您的文件中:

/etc/ssh/sshd_config

#Port 22
Port 4444

完成后保存并关闭文件。 要实施更改,您必须重新启动 SSH 守护程序。

在 Ubuntu/Debian 上:

sudo service ssh restart

在 CentOS/Fedora 上:

sudo service sshd restart

守护程序重新启动后,您将需要通过指定端口号进行身份验证(在前面的部分中进行了演示)。

限制可以通过 SSH 连接的用户

要明确限制能够通过 SSH 登录的用户帐户,您可以采用几种不同的方法,每种方法都涉及编辑 SSH 守护程序配置文件。

在您的远程服务器上,现在使用 root 或 sudo 权限打开此文件:

sudo nano /etc/ssh/sshd_config

指定允许登录的帐户的第一种方法是使用 AllowUsers 指令。 在文件中搜索 AllowUsers 指令。 如果不存在,请在任何地方创建它。 在指令之后,列出应该允许通过 SSH 登录的用户帐户:

/etc/ssh/sshd_config

AllowUsers user1 user2

保存并关闭文件。 重新启动守护程序以实施您的更改。

在 Ubuntu/Debian 上:

sudo service ssh restart

在 CentOS/Fedora 上:

sudo service sshd restart

如果您更熟悉组管理,则可以使用 AllowGroups 指令。 如果是这种情况,只需添加一个应允许 SSH 访问的组(我们将创建此组并立即添加成员):

/etc/ssh/sshd_config

AllowGroups sshmembers

保存并关闭文件。

现在,您可以通过键入以下内容创建与您指定的组匹配的系统组(没有主目录):

sudo groupadd -r sshmembers

确保将所需的任何用户帐户添加到该组。 这可以通过键入:

sudo usermod -a -G sshmembers user1
sudo usermod -a -G sshmembers user2

现在,重新启动 SSH 守护程序以实施您的更改。

在 Ubuntu/Debian 上:

sudo service ssh restart

在 CentOS/Fedora 上:

sudo service sshd restart

禁用根登录

通常建议您在设置具有 sudo 权限的 SSH 用户帐户后完全禁用通过 SSH 的 root 登录。

为此,请在远程服务器上使用 root 或 sudo 打开 SSH 守护程序配置文件。

sudo nano /etc/ssh/sshd_config

在里面,搜索一个名为 PermitRootLogin 的指令。 如果已注释,请取消注释。 将值更改为“否”:

/etc/ssh/sshd_config

PermitRootLogin no

保存并关闭文件。 要实施您的更改,请重新启动 SSH 守护程序。

在 Ubuntu/Debian 上:

sudo service ssh restart

在 CentOS/Fedora 上:

sudo service sshd restart

允许特定命令的 Root 访问权限

在某些情况下,您可能希望通常禁用 root 访问,但启用它以允许某些应用程序正确运行。 这方面的一个例子可能是备份例程。

这可以通过 root 用户的 authorized_keys 文件来完成,该文件包含授权使用该帐户的 SSH 密钥。

将您希望用于此过程的本地计算机中的密钥(我们建议为每个自动过程创建一个新密钥)添加到服务器上 root 用户的 authorized_keys 文件中。 我们将在此处使用 ssh-copy-id 命令进行演示,但您可以使用我们在其他部分中讨论的任何复制密钥的方法:

ssh-copy-id root@remote_host

现在,登录到远程服务器。 我们将需要调整 authorized_keys 文件中的条目,因此使用 root 或 sudo 访问权限打开它:

sudo nano /root/.ssh/authorized_keys

在您上传的密钥所在行的开头,添加一个 command= 列表,该列表定义了此密钥对其有效的命令。 这应该包括可执行文件的完整路径,以及任何参数:

/root/.ssh/authorized_keys

command="/path/to/command arg1 arg2" ssh-rsa ...

完成后保存并关闭文件。

现在,使用 root 或 sudo 权限打开 sshd_config 文件:

sudo nano /etc/ssh/sshd_config

找到指令 PermitRootLogin,并将值更改为 forced-commands-only。 当为密钥指定命令时,这将仅允许 SSH 密钥登录使用 root:

/etc/ssh/sshd_config

PermitRootLogin forced-commands-only

保存并关闭文件。 重新启动 SSH 守护程序以实施您的更改。

在 Ubuntu/Debian 上:

sudo service ssh restart

在 CentOS/Fedora 上:

sudo service sshd restart

将 X 应用程序显示转发给客户端

SSH 守护进程可以配置为自动将服务器上 X 应用程序的显示转发到客户端机器。 要使其正常运行,客户端必须配置并启用 X windows 系统。

要启用此功能,请登录到您的远程服务器并以 root 或使用 sudo 权限编辑 sshd_config 文件:

sudo nano /etc/ssh/sshd_config

搜索 X11Forwarding 指令。 如果已注释掉,请取消注释。 如有必要,创建它并将值设置为“yes”:

/etc/ssh/sshd_config

X11Forwarding yes

保存并关闭文件。 重新启动 SSH 守护程序以实施这些更改。

在 Ubuntu/Debian 上:

sudo service ssh restart

在 CentOS/Fedora 上:

sudo service sshd restart

要连接到服务器并转发应用程序的显示,您必须在连接时从客户端传递 -X 选项:

ssh -X username@remote_host

通过此会话在服务器上启动的图形应用程序应显示在本地计算机上。 性能可能有点慢,但在紧要关头它非常有帮助。

客户端配置选项

在下一节中,我们将重点介绍您可以在连接的客户端进行的一些调整。

定义服务器特定的连接信息

在本地计算机上,您可以为连接到的部分或全部服务器定义单独的配置。 这些可以存储在 ~/.ssh/config 文件中,您的 SSH 客户端每次调用时都会读取该文件。

在本地计算机上的文本编辑器中创建或打开此文件:

nano ~/.ssh/config

在内部,您可以通过在每个配置选项中引入 Host 关键字和别名来定义单独的配置选项。 在此和缩进下,您可以定义 ssh_config 手册页中的任何指令:

man ssh_config

一个示例配置是:

~/.ssh/config

Host testhost
    HostName your_domain
    Port 4444
    User demo

然后,您可以使用用户名 demo 连接到端口 4444 上的 your_domain,只需键入:

ssh testhost

您还可以使用通配符来匹配多个主机。 请记住,以后的匹配可以覆盖较早的匹配。 因此,您应该将最常见的匹配放在顶部。 例如,您可以默认所有连接不允许 X 转发,并通过在文件中包含以下内容来覆盖 your_domain

~/.ssh/config

Host *
    ForwardX11 no

Host testhost
    HostName your_domain
    ForwardX11 yes
    Port 4444
    User demo

完成后保存并关闭文件。

保持连接活动以避免超时

如果您在准备好之前发现自己与 SSH 会话断开连接,则您的连接可能会超时。

您可以将客户端配置为每隔一段时间向服务器发送一个数据包,以避免这种情况:

在您的本地计算机上,您可以通过编辑 ~/.ssh/config 文件为每个连接进行配置。 现在打开它:

nano ~/.ssh/config

如果尚不存在,请在文件顶部定义一个匹配所有主机的部分。 将 ServerAliveInterval 设置为“120”,每两分钟向服务器发送一个数据包。 这应该足以通知服务器不要关闭连接:

~/.ssh/config

Host *
    ServerAliveInterval 120

完成后保存并关闭文件。

禁用主机检查

默认情况下,每当您连接到新服务器时,都会显示远程 SSH 守护程序的主机密钥指纹。

The authenticity of host '111.111.11.111 (111.111.11.111)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes

这样您就可以验证您尝试连接的主机的真实性,并发现恶意用户可能试图伪装成远程主机的实例。

在某些情况下,您可能希望禁用此功能。 注意:这可能是一个很大的安全风险,所以如果你像这样设置你的系统,请确保你知道你在做什么。

要进行更改,请在本地计算机上打开 ~/.ssh/config 文件:

nano ~/.ssh/config

如果尚不存在,请在文件顶部定义一个匹配所有主机的部分。 将 StrictHostKeyChecking 指令设置为 no 以自动将新主机添加到 known_hosts 文件中。 将 UserKnownHostsFile 设置为 /dev/null 以不在新主机或更改主机上发出警告:

~/.ssh/config

Host *
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null

您可以通过反转其他主机的这些选项来逐个启用检查。 StrictHostKeyChecking 的默认值为 ask

~/.ssh/config

Host *
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null

Host testhost
    HostName your_domain
    StrictHostKeyChecking ask
    UserKnownHostsFile /home/demo/.ssh/known_hosts

通过单个 TCP 连接多路复用 SSH

在某些情况下,建立新的 TCP 连接所需的时间可能比您希望的要长。 如果您要与同一台机器建立多个连接,则可以利用多路复用。

SSH 多路复用为多个 SSH 会话重复使用相同的 TCP 连接。 这消除了建立新会话所需的一些工作,可能会加快速度。 由于其他原因,限制连接数量也可能会有所帮助。

要设置多路复用,您可以手动设置连接,也可以将客户端配置为在可用时自动使用多路复用。 我们将在这里演示第二个选项。

要配置多路复用,请在本地计算机上编辑 SSH 客户端的配置文件:

nano ~/.ssh/config

如果文件顶部还没有通配符主机定义,现在添加一个(如 Host *)。 我们将设置 ControlMasterControlPathControlPersist 值来建立我们的多路复用配置。

ControlMaster 应设置为“auto”,以便在可能的情况下自动允许多路复用。 ControlPath 将建立控制套接字的路径。 第一个会话将创建此套接字,后续会话将能够找到它,因为它由用户名、主机和端口标记。

ControlPersist 选项设置为 1 将允许初始主连接在后台运行。 1 指定 TCP 连接应在最后一个 SSH 会话关闭后一秒自动终止:

/.ssh/config

Host *
    ControlMaster auto
    ControlPath ~/.ssh/multiplex/%r@%h:%p
    ControlPersist 1

完成后保存并关闭文件。 现在,我们需要实际创建我们在控制路径中指定的目录:

mkdir ~/.ssh/multiplex

现在,与同一台机器建立的任何会话都将尝试使用现有的套接字和 TCP 连接。 当最后一个会话存在时,连接将在一秒钟后断开。

如果由于某种原因您需要暂时绕过多路复用配置,您可以通过将 -S 标志与 none 一起传递来实现:

ssh -S none username@remote_host

设置 SSH 隧道

通过安全的 SSH 隧道传输其他流量是解决限制性防火墙设置的绝佳方法。 这也是加密其他未加密的网络流量的好方法。

配置到服务器的本地隧道

SSH 连接可用于将流量从本地主机上的端口传输到远程主机上的端口。

本地连接是一种通过远程主机从本地计算机访问网络位置的方法。 首先,与您的远程主机建立 SSH 连接。 在远程服务器上,与用户提供的外部(或内部)网络地址建立连接,并且到该位置的流量通过指定端口通过隧道传输到本地计算机。

这通常用于通过绕过防火墙来隧道到限制较少的网络环境。 另一个常见用途是从远程位置访问“仅限本地主机”的 Web 界面。

要建立到远程服务器的本地隧道,您需要在连接时使用 -L 参数,并且必须提供三个附加信息:

  • 您希望访问隧道连接的本地端口。
  • 您希望远程主机连接到的主机。
  • 您希望远程主机连接的端口。

这些按上述顺序(用冒号分隔)作为 -L 标志的参数给出。 我们还将使用 -f 标志,它使 SSH 在执行之前进入后台,以及 -N 标志,它不会打开 shell 或在远程端执行程序。

例如,要连接到远程主机上端口 80 上的 your_domain,使连接在本地计算机上的端口 8888 上可用,您可以键入:

ssh -f -N -L 8888:your_domain:80 username@remote_host

现在,如果您将本地 Web 浏览器指向 127.0.0.1:8888,您应该会看到端口 80your_domain 的任何内容。

更一般的语法指南是:

ssh -L your_port:site_or_IP_to_access:site_port username@host

由于连接在后台,您必须找到它的 PID 才能杀死它。 您可以通过搜索您转发的端口来做到这一点:

ps aux | grep 8888
Output1001      5965  0.0  0.0  48168  1136 ?        Ss   12:28   0:00 ssh -f -N -L 8888:your_domain:80 username@remote_host
1001      6113  0.0  0.0  13648   952 pts/2    S+   12:37   0:00 grep --colour=auto 8888

然后,您可以通过定位 PID 来终止该进程,该 PID 是与您的 SSH 命令匹配的行的第二列中的数字:

kill 5965

另一种选择是在没有 -f 标志的情况下启动连接 而没有 。 这将使连接保持在前台,防止您在转发期间使用终端窗口。 这样做的好处是您可以通过键入 CTRL-C 轻松终止隧道。

配置到服务器的远程隧道

SSH 连接可用于将流量从本地主机上的端口传输到远程主机上的端口。

在远程隧道中,与远程主机建立连接。 在创建隧道期间,指定了一个 remote 端口。 然后,远程主机上的此端口将通过隧道连接到从本地计算机连接的主机和端口组合。 这将允许远程计算机通过您的本地计算机访问主机。

如果您需要允许访问锁定到外部连接的内部网络,这将很有用。 如果防火墙允许连接 out 网络,这将允许您连接到远程计算机并将流量从该计算机传输到内部网络上的某个位置。

要建立到远程服务器的远程隧道,您需要在连接时使用 -R 参数,并且必须提供三个附加信息:

  • 远程主机可以访问隧道连接的端口。
  • 您希望本地计算机连接到的主机。
  • 您希望本地计算机连接到的端口。

这些按上述顺序(用冒号分隔)作为 -R 标志的参数给出。 我们还将使用 -f 标志,它使 SSH 在执行之前进入后台,以及 -N 标志,它不会打开 shell 或在远程端执行程序。

例如,要连接到我们本地计算机上端口 80 上的 your_domain,使连接在我们的远程主机上的端口 8888 上可用,您可以键入:

ssh -f -N -R 8888:your_domain:80 username@remote_host

现在,在远程主机上,打开 Web 浏览器到 127.0.0.1:8888 将允许您查看端口 80your_domain 的任何内容。

更一般的语法指南是:

ssh -R remote_port:site_or_IP_to_access:site_port username@host

由于连接在后台,您必须找到它的 PID 才能杀死它。 您可以通过搜索您转发的端口来做到这一点:

ps aux | grep 8888
Output1001      5965  0.0  0.0  48168  1136 ?        Ss   12:28   0:00 ssh -f -N -R 8888:your_domain:80 username@remote_host
1001      6113  0.0  0.0  13648   952 pts/2    S+   12:37   0:00 grep --colour=auto 8888

然后,您可以通过针对与您的 SSH 命令匹配的行的 PID(第二列中的数字)来终止该进程:

kill 5965

另一种选择是在没有 -f 标志的情况下启动连接 而没有 。 这将使连接保持在前台,防止您在转发期间使用终端窗口。 这样做的好处是您可以通过键入 CTRL-C 轻松终止隧道。

配置到远程服务器的动态隧道

SSH 连接可用于将流量从本地主机上的端口传输到远程主机上的端口。

动态隧道类似于本地隧道,它允许本地计算机通过 远程主机连接到其他资源。 动态隧道通过简单地指定一个本地端口来实现这一点。 希望利用此端口进行隧道传输的应用程序必须能够使用 SOCKS 协议进行通信,以便可以在隧道的另一端正确重定向数据包。

传递到此本地端口的流量将被发送到远程主机。 从那里,SOCKS 协议将被解释为建立到所需终端位置的连接。 这种设置允许支持 SOCKS 的应用程序通过远程服务器连接到任意数量的位置,而无需多个静态隧道。

为了建立连接,我们将传递 -D 标志以及我们希望访问隧道的本地端口。 我们还将使用 -f 标志,它使 SSH 在执行之前进入后台,以及 -N 标志,它不会打开 shell 或在远程端执行程序。

例如,要在端口 7777 上建立隧道,您可以键入:

ssh -f -N -D 7777 username@remote_host

从这里,您可以开始将支持 SOCKS 的应用程序(如 Web 浏览器)指向您选择的端口。 应用程序会将其信息发送到与端口关联的套接字中。

将流量引导到 SOCKS 端口的方法因应用程序而异。 例如,在 Firefox 中,一般位置是首选项 > 高级 > 设置 > 手动代理配置。 在 Chrome 中,您可以通过设置 --proxy-server= 标志来启动应用程序。 您将需要使用 localhost 接口和您转发的端口。

由于连接在后台,您必须找到它的 PID 才能杀死它。 您可以通过搜索您转发的端口来做到这一点:

ps aux | grep 8888
Output1001      5965  0.0  0.0  48168  1136 ?        Ss   12:28   0:00 ssh -f -N -D 7777 username@remote_host
1001      6113  0.0  0.0  13648   952 pts/2    S+   12:37   0:00 grep --colour=auto 8888

然后,您可以通过针对与您的 SSH 命令匹配的行的 PID(第二列中的数字)来终止该进程:

kill 5965

另一种选择是在没有 -f 标志的情况下启动连接 而没有 。 这将使连接保持在前台,防止您在转发期间使用终端窗口。 这样做的好处是您可以通过键入 CTRL-C 轻松终止隧道。

使用 SSH 转义码控制连接

即使在建立 SSH 会话之后,也可以从终端内控制连接。 我们可以使用称为 SSH 转义码的东西来做到这一点,它允许我们在会话中与本地 SSH 软件进行交互。

强制从客户端断开连接(如何退出卡住或冻结的会话)

OpenSSH 最有用的功能之一是在很大程度上没有引起注意,它能够从内部控制会话的某些方面。

这些命令可以在 SSH 会话中以 ~ 控制字符开始执行。 仅当控制命令是在换行符之后键入的第一件事时,才会解释控制命令,因此在使用之前始终按 ENTER 一次或两次。

最有用的控件之一是启动与客户端断开连接的能力。 SSH 连接通常由服务器关闭,但如果服务器遇到问题或连接已断开,这可能会成为问题。 通过使用客户端断开连接,可以从客户端干净地关闭连接。

要关闭来自客户端的连接,请使用带点的控制字符 (~)。 如果您的连接出现问题,您可能会处于似乎卡住的终端会话中。 尽管没有反馈来执行客户端断开连接,但仍键入命令:

[ENTER]
~.

连接应立即关闭,将您返回到本地 shell 会话。

将 SSH 会话置于后台

OpenSSH 最有用的功能之一是在很大程度上被忽视的,它能够从连接中控制会话的某些方面。

这些命令可以从 SSH 连接中以 ~ 控制字符开始执行。 仅当控制命令是在换行符之后键入的第一件事时,才会解释控制命令,因此在使用之前总是按 ENTER 一次或两次。

它提供的一项功能是将 SSH 会话置于后台。 为此,我们需要提供控制字符(~),然后执行传统的键盘快捷键来后台任务(CTRL-z):

[ENTER]
~[CTRL-z]

这会将连接置于后台,将您返回到本地 shell 会话。 要返回您的 SSH 会话,您可以使用传统的作业控制机制。

您可以通过键入以下内容立即重新激活您最近的后台任务:

fg

如果您有多个后台任务,您可以通过键入以下内容查看可用作业:

jobs
Output[1]+  Stopped                 ssh username@some_host
[2]   Stopped                 ssh username@another_host

然后,您可以使用第一列中带有百分号的索引将任何任务置于前台:

fg %2

更改现有 SSH 连接上的端口转发选项

OpenSSH 最有用的功能之一是在很大程度上被忽视的,它能够从连接中控制会话的某些方面。

这些命令可以从 SSH 连接中以 ~ 控制字符开始执行。 仅当控制命令是在换行符之后键入的第一件事时,才会解释控制命令,因此在使用之前始终按 ENTER 一次或两次。

这允许用户在建立连接后更改端口转发配置。 这允许您即时创建或拆除端口转发规则。

这些功能是 SSH 命令行界面的一部分,可以在会话期间通过使用控制字符 (~) 和“C”来访问:

[ENTER]
~C
ssh>

您将看到一个 SSH 命令提示符,其中包含一组非常有限的有效命令。 要查看可用选项,您可以在此提示中键入 -h。 如果没有返回任何内容,您可能需要通过使用 ~v 几次来增加 SSH 输出的详细程度:

[ENTER]
~v
~v
~v
~C
-h
Commands:
      -L[bind_address:]port:host:hostport    Request local forward
      -R[bind_address:]port:host:hostport    Request remote forward
      -D[bind_address:]port                  Request dynamic forward
      -KL[bind_address:]port                 Cancel local forward
      -KR[bind_address:]port                 Cancel remote forward
      -KD[bind_address:]port                 Cancel dynamic forward

如您所见,您可以使用适当的选项轻松实现任何转发选项(有关更多信息,请参阅转发部分)。 您还可以使用在转发类型字母前指定“K”的关联“kill”命令来破坏隧道。 例如,要杀死本地前锋 (-L),您可以使用 -KL 命令。 您只需要为此提供端口。

因此,要设置本地端口转发,您可以键入:

[ENTER]
~C
-L 8888:127.0.0.1:80

您本地计算机上的端口 8888 现在将能够与您正在连接的主机上的 Web 服务器通信。 完成后,您可以通过键入以下内容将其关闭:

[ENTER]
~C
-KL 8888

结论

上述说明应涵盖大多数用户日常所需的有关 SSH 的大部分信息。 如果您有其他提示或希望分享您最喜欢的配置和方法,请随时使用下面的评论。