如何在 Linux 服务器上配置基于 SSH 密钥的身份验证
介绍
SSH,或安全外壳,是一种用于管理服务器和与服务器通信的加密协议。使用 Linux 服务器时,您可能经常将大部分时间花在通过 SSH 连接到服务器的终端会话中。
虽然有几种不同的方法可以登录 SSH 服务器,但在本指南中,我们将重点介绍如何设置 SSH 密钥。 SSH 密钥提供了一种极其安全的登录服务器的方式。因此,这是我们为所有用户推荐的方法。
SSH 密钥如何工作?
SSH 服务器可以使用多种不同的方法对客户端进行身份验证。其中最基本的是密码验证,它易于使用,但不是最安全的。
尽管密码以安全的方式发送到服务器,但它们通常不够复杂或不够长,无法抵御反复、持续的攻击者。现代处理能力与自动化脚本相结合,使得暴力破解受密码保护的帐户成为可能。尽管还有其他方法可以增加额外的安全性(fail2ban
等),但 SSH 密钥被证明是一种可靠且安全的替代方法。
SSH 密钥对是两个加密安全密钥,可用于向 SSH 服务器验证客户端。每个密钥对由一个公钥和一个私钥组成。
私钥由客户端保留,应绝对保密。私钥的任何泄露都将允许攻击者登录到配置有关联公钥的服务器,而无需额外的身份验证。作为额外的预防措施,可以使用密码短语在磁盘上加密密钥。
关联的公钥可以自由共享而不会产生任何负面影响。公钥可用于加密只有私钥才能解密的消息。此属性用作使用密钥对进行身份验证的方式。
公钥被上传到您希望能够使用 SSH 登录的远程服务器。密钥被添加到您将要登录的用户帐户中的一个特殊文件中,该文件名为 ~/.ssh/authorized_keys
。
当客户端尝试使用 SSH 密钥进行身份验证时,服务器可以测试客户端是否拥有私钥。如果客户端可以证明它拥有私钥,则会生成 shell 会话或执行请求的命令。
第 1 步 — 创建 SSH 密钥
为服务器配置 SSH 密钥身份验证的第一步是在本地计算机上生成 SSH 密钥对。
为此,我们可以使用一个名为 ssh-keygen
的特殊实用程序,它包含在标准的 OpenSSH 工具套件中。默认情况下,这将创建一个 3072 位 RSA 密钥对。
在本地计算机上,通过键入以下内容生成 SSH 密钥对:
- ssh-keygen
OutputGenerating public/private rsa key pair.
Enter file in which to save the key (/home/username/.ssh/id_rsa):
该实用程序将提示您为将生成的密钥选择一个位置。默认情况下,密钥将存储在用户主目录下的 ~/.ssh
目录中。私钥将称为 id_rsa
,关联的公钥将称为 id_rsa.pub
。
通常,最好在此阶段坚持使用默认位置。这样做将允许您的 SSH 客户端在尝试进行身份验证时自动找到您的 SSH 密钥。如果您想选择非标准路径,请立即输入,否则,按 ENTER
接受默认值。
如果您之前生成了 SSH 密钥对,您可能会看到如下所示的提示:
Output/home/username/.ssh/id_rsa already exists.
Overwrite (y/n)?
如果您选择覆盖磁盘上的密钥,您将无法再使用以前的密钥进行身份验证。选择是时要非常小心,因为这是一个无法逆转的破坏性过程。
OutputCreated directory '/home/username/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
接下来,系统将提示您输入密钥的密码。这是一个可选的密码,可用于加密磁盘上的私钥文件。
如果您仍然需要输入密码,您可能想知道 SSH 密钥有什么优势。一些优点是:
- SSH 私钥(可以用密码保护的部分)永远不会暴露在网络上。密码仅用于解密本地计算机上的密钥。这意味着基于网络的暴力破解将无法破解密码。
- 私钥保存在一个受限制的目录中。 SSH 客户端将无法识别未保存在受限目录中的私钥。密钥本身也必须具有受限的权限(读取和写入仅对所有者可用)。这意味着系统上的其他用户无法窥探。
- 任何希望破解 SSH 私钥密码的攻击者必须已经可以访问系统。这意味着他们已经可以访问您的用户帐户或根帐户。如果您处于这种情况,密码可以阻止攻击者立即登录到您的其他服务器。这有望让您有时间创建和实施新的 SSH 密钥对,并从受损密钥中删除访问权限。
由于私钥永远不会暴露在网络中并通过文件权限受到保护,因此除您(和 root 用户)之外的任何人都不应访问该文件。在这些条件被破坏的情况下,密码短语可作为额外的保护层。
密码是一个可选的添加。如果输入一个,则每次使用此密钥时都必须提供它(除非您正在运行存储解密密钥的 SSH 代理软件)。我们建议使用密码,但如果您不想设置密码,可以按 ENTER
绕过此提示。
OutputYour identification has been saved in /home/username/.ssh/id_rsa.
Your public key has been saved in /home/username/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:CAjsV9M/tt5skazroTc1ZRGCBz+kGtYUIPhRvvZJYBs username@hostname
The key's randomart image is:
+---[RSA 3072]----+
|o ..oo.++o .. |
| o o +o.o.+... |
|. . + oE.o.o . |
| . . oo.B+ .o |
| . .=S.+ + |
| . o..* |
| .+= o |
| .=.+ |
| .oo+ |
+----[SHA256]-----+
您现在拥有可用于身份验证的公钥和私钥。下一步是将公钥放在您的服务器上,以便您可以使用 SSH 密钥身份验证登录。
第 2 步 — 将 SSH 公钥复制到您的服务器
注意:本教程的先前版本包含将 SSH 公钥添加到您的 DigitalOcean 帐户的说明。这些说明现在可以在我们的 DigitalOcean 产品文档的 SSH 密钥 部分找到。
有多种方法可以将您的公钥上传到您的远程 SSH 服务器。您使用的方法在很大程度上取决于您可用的工具和当前配置的详细信息。
以下方法都产生相同的最终结果。首先介绍最简单、自动化程度最高的方法,随后的每个方法都需要额外的手动步骤。仅当您无法使用上述方法时,才应遵循这些。
使用 ssh-copy-id 复制你的公钥
将公钥复制到现有服务器的最简单方法是使用名为 ssh-copy-id
的实用程序。由于其简单性,如果可用,建议使用此方法。
ssh-copy-id
工具包含在许多发行版的 OpenSSH 软件包中,因此您可能已经在本地系统上使用了它。要使用此方法,您当前必须具有对服务器的基于密码的 SSH 访问权限。
要使用该实用程序,您需要指定要连接的远程主机,以及您具有基于密码的 SSH 访问权限的用户帐户。这是您的公共 SSH 密钥将被复制到的帐户。
语法是:
- ssh-copy-id username@remote_host
您可能会看到这样的消息:
OutputThe authenticity of host '203.0.113.1 (203.0.113.1)' 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
并按 ENTER
继续。
接下来,该实用程序将扫描您的本地帐户以查找我们之前创建的 id_rsa.pub
密钥。当它找到密钥时,它会提示您输入远程用户帐户的密码:
Output/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
username@203.0.113.1's password:
输入密码(出于安全目的不会显示您输入的内容)并按 ENTER
。该实用程序将使用您提供的密码连接到远程主机上的帐户。然后它将您的 ~/.ssh/id_rsa.pub
密钥的内容复制到远程帐户的主 ~/.ssh
目录中名为 authorized_keys< 的文件中/代码>。
您将看到如下所示的输出:
OutputNumber of key(s) added: 1
Now try logging into the machine, with: "ssh 'username@203.0.113.1'"
and check to make sure that only the key(s) you wanted were added.
此时,您的 id_rsa.pub
密钥已上传到远程帐户。您可以继续下一节。
使用 SSH 复制您的公钥
如果您没有可用的 ssh-copy-id
,但您有基于密码的 SSH 访问您服务器上的帐户,您可以使用传统的 SSH 方法上传您的密钥。
为此,我们可以在本地计算机上输出 SSH 公钥的内容,并通过 SSH 连接将其传输到远程服务器。另一方面,我们可以确保 ~/.ssh
目录存在于我们正在使用的帐户下,然后将我们通过管道传输的内容输出到一个名为 authorized_keys
的文件中在这个目录中。
我们将使用 >>>
重定向符号来附加内容而不是覆盖它。这将使我们能够在不破坏之前添加的密钥的情况下添加密钥。
完整命令如下所示:
- cat ~/.ssh/id_rsa.pub | ssh username@remote_host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
您可能会看到这样的消息:
OutputThe authenticity of host '203.0.113.1 (203.0.113.1)' 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
并按 ENTER
继续。
之后,系统将提示您输入您尝试连接的帐户的密码:
Outputusername@203.0.113.1's password:
输入密码后,您的 id_rsa.pub
密钥的内容将被复制到远程用户帐户的 authorized_keys
文件的末尾。如果成功,请继续下一节。
手动复制您的公钥
如果您没有基于密码的 SSH 访问服务器的可用权限,则必须手动执行上述过程。
您的 id_rsa.pub
文件的内容必须以某种方式添加到远程计算机上位于 ~/.ssh/authorized_keys
的文件中。
要显示您的 id_rsa.pub
密钥的内容,请在您的本地计算机中键入:
- cat ~/.ssh/id_rsa.pub
您将看到密钥的内容,可能如下所示:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCqql6MzstZYh1TmWWv11q5O3pISj2ZFl9HgH1JLknLLx44+tXfJ7mIrKNxOOwxIxvcBF8PXSYvobFYEZjGIVCEAjrUzLiIxbyCoxVyle7Q+bqgZ8SeeM8wzytsY+dVGcBxF6N4JS+zVk5eMcV385gG3Y6ON3EG112n6d+SMXY0OEBIcO6x+PnUSGHrSgpBgX7Ks1r7xqFa7heJLLt2wWwkARptX7udSq05paBhcpB0pHtA1Rfz3K2B+ZVIpSDfki9UVKzT8JUmwW6NNzSgxUfQHGwnW7kj4jp4AT0VZk3ADw497M2G/12N0PPB5CnhHf7ovgy6nL1ikrygTKRFmNZISvAcywB9GVqNAVE+ZHDSCuURNsAInVzgYo9xgJDW8wUw2o8U77+xiFxgI5QSZX3Iq7YLMgeksaO4rBJEa54k8m5wEiEE1nUhLuJ0X/vh2xPff6SQ1BL/zkOhvJCACK6Vb15mDOeCSq54Cr7kvS46itMosi/uS66+PujOO+xt/2FWYepz6ZlN70bRly57Q06J+ZJoc9FfBCbCyYH7U/ASsmY095ywPsBo1XQ9PqhnN1/YOorJ068foQDNVpm146mUpILVxmq41Cj55YKHEazXGsdBIbXWhcrRf4G2fJLRcGUr9q8/lERo9oxRm5JFX6TCmj6kmiFqv+Ow9gI0x8GvaQ== username@hostname
使用可用的任何方法访问远程主机。这可能是您的基础架构提供商提供的基于 Web 的控制台。
注意:如果您使用的是 DigitalOcean Droplet,请参阅 DigitalOcean 产品文档中的故障恢复控制台文档。
一旦您可以访问您在远程服务器上的帐户,您应该确保创建了 ~/.ssh
目录。此命令将在必要时创建目录,如果目录已存在,则不执行任何操作:
- mkdir -p ~/.ssh
现在,您可以在该目录中创建或修改 authorized_keys
文件。您可以将 id_rsa.pub
文件的内容添加到 authorized_keys
文件的末尾,必要时使用以下命令创建它:
- echo public_key_string >> ~/.ssh/authorized_keys
在上述命令中,将 public_key_string
替换为您在本地执行的 cat ~/.ssh/id_rsa.pub
命令的输出系统。它应该以 ssh-rsa AAAA...
或类似的开头。
如果可行,您可以继续测试新的基于密钥的 SSH 身份验证。
第 3 步 — 使用 SSH 密钥向您的服务器进行身份验证
如果您已成功完成上述过程之一,则您应该能够在没有远程帐户密码的情况下登录到远程主机。
该过程大致相同:
- ssh username@remote_host
如果这是您第一次连接到该主机(如果您使用了上面最后一种方法),您可能会看到如下内容:
OutputThe authenticity of host '203.0.113.1 (203.0.113.1)' 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
然后按 ENTER
继续。
如果您没有为您的私钥提供密码,您将立即登录。如果您在创建密钥时为私钥提供了密码,您现在需要输入它。之后,将使用远程系统上的帐户为您创建一个新的 shell 会话。
如果成功,请继续了解如何锁定服务器。
第 4 步 — 在您的服务器上禁用密码验证
如果您能够在没有密码的情况下使用 SSH 登录您的帐户,则您已成功为您的帐户配置基于 SSH 密钥的身份验证。但是,您基于密码的身份验证机制仍处于活动状态,这意味着您的服务器仍会受到暴力攻击。
在完成本节中的步骤之前,请确保您已为此服务器上的根帐户配置了基于 SSH 密钥的身份验证,或者最好为该服务器上的帐户配置了基于 SSH 密钥的身份验证 sudo
访问。此步骤将锁定基于密码的登录,因此确保您仍然能够获得管理访问权限至关重要。
一旦满足上述条件,请使用 SSH 密钥以 root 身份或具有 sudo
权限的帐户登录远程服务器。打开 SSH 守护进程的配置文件:
- sudo nano /etc/ssh/sshd_config
在文件中,搜索名为 PasswordAuthentication
的指令。这可能会被注释掉。通过删除行开头的任何 #
取消注释该行,并将值设置为 no
。这将禁用您使用帐户密码通过 SSH 登录的能力:
PasswordAuthentication no
完成后保存并关闭文件。要真正实施我们刚刚所做的更改,您必须重新启动该服务。
在大多数 Linux 发行版上,您可以发出以下命令来执行此操作:
- sudo systemctl restart ssh
完成此步骤后,您已成功将 SSH 守护程序转换为仅响应 SSH 密钥。
结论
您现在应该在您的服务器上配置并运行基于 SSH 密钥的身份验证,允许您在不提供帐户密码的情况下登录。从这里开始,您可以前往许多方向。如果您想了解有关使用 SSH 的更多信息,请查看我们的 SSH 基础指南。