如何在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 密钥密码的攻击者必须已经可以访问系统。 这意味着他们已经可以访问您的用户帐户或 root 帐户。 如果您处于此位置,则密码可以阻止攻击者立即登录您的其他服务器。 这有望让您有时间创建和实施新的 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/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 密钥的身份验证。 但是,您的基于密码的身份验证机制仍然处于活动状态,这意味着您的服务器仍然面临暴力攻击。
在完成本节中的步骤之前,请确保您为此服务器上的 root 帐户配置了基于 SSH 密钥的身份验证,或者最好为该服务器上的帐户配置了基于 SSH 密钥的身份验证此服务器具有 sudo
访问权限。 此步骤将锁定基于密码的登录,因此确保您仍然能够获得管理访问权限至关重要。
满足上述条件后,使用 SSH 密钥登录远程服务器,以 root 身份或具有 sudo
权限的帐户。 打开 SSH 守护进程的配置文件:
sudo nano /etc/ssh/sshd_config
在文件中,搜索名为 PasswordAuthentication
的指令。 这可能会被注释掉。 通过删除行开头的任何 #
取消注释该行,并将值设置为 no
。 这将禁用您使用帐户密码通过 SSH 登录的能力:
/etc/ssh/sshd_config
PasswordAuthentication no
完成后保存并关闭文件。 要真正实现我们刚刚所做的更改,您必须重新启动服务。
在大多数 Linux 发行版上,您可以发出以下命令来执行此操作:
sudo systemctl restart ssh
完成此步骤后,您已成功将 SSH 守护程序转换为仅响应 SSH 密钥。
结论
您现在应该在您的服务器上配置并运行基于 SSH 密钥的身份验证,允许您在不提供帐户密码的情况下登录。 从这里,您可以前往许多方向。 如果您想了解有关使用 SSH 的更多信息,请查看我们的 SSH 基本指南 。