本文详细介绍了如何在Linux服务器上设置SSH密钥对进行身份验证,包括创建密钥对、将公钥上传到服务器以及禁用密码身份验证,以提高安全性。
介绍
SSH(Secure Shell)是一种加密协议,用于管理和与服务器通信。在使用 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
[本地环境] 生成公钥/私钥 rsa 密钥对。 输入要保存密钥的文件(/home/username/.ssh/id_rsa):
该实用程序将提示您选择要生成的密钥的位置。默认情况下,密钥将存储在用户主目录中的 ~/.ssh
目录中。私钥将被称为 id_rsa
,相关的公钥将被称为 id_rsa.pub
。
通常,在这个阶段最好使用默认位置。这样做将允许您的 SSH 客户端在尝试进行身份验证时自动找到您的 SSH 密钥。如果您想选择非标准路径,请现在输入该路径,否则按 ENTER
接受默认值。
如果您之前生成过 SSH 密钥对,您可能会看到类似以下的提示:
[本地环境] /home/username/.ssh/id_rsa 已经存在。 覆盖(y/n)?
如果选择覆盖磁盘上的密钥,您将无法再使用先前的密钥进行身份验证。在选择是时要非常小心,因为这是一个不可逆转的破坏性过程。
[本地环境] 创建目录 '/home/username/.ssh'。 输入密码短语(留空表示没有密码短语): 再次输入密码短语:
接下来,您将被提示为密钥输入密码短语。这是一个可选的密码短语,可用于加密磁盘上的私钥文件。
您可能会想知道,如果您仍然需要输入密码短语,SSH 密钥提供了哪些优势。其中一些优势包括:
- 私有 SSH 密钥(可以受密码短语保护的部分)永远不会在网络上暴露。密码短语仅用于在本地机器上解密密钥。这意味着网络基础的暴力破解将无法针对密码短语进行。
- 私钥保存在受限制的目录中。SSH 客户端将不会识别未保存在受限制目录中的私钥。密钥本身也必须具有受限制的权限(仅对所有者可用的读和写权限)。这意味着系统上的其他用户无法窥视。
- 任何希望破解私有 SSH 密钥密码短语的攻击者必须已经访问系统。这意味着他们已经可以访问您的用户帐户或 root 帐户。如果您处于这种位置,密码短语可以防止攻击者立即登录到您的其他服务器。这将希望给您时间创建和实施新的 SSH 密钥对,并从受损的密钥中删除访问权限。
由于私钥永远不会暴露在网络上,并且通过文件权限进行保护,因此该文件永远不应该对除您(和root用户)以外的任何人可访问。密码短语作为一个额外的保护层,以防这些条件被破坏。
密码短语是一个可选的附加项。如果输入密码短语,您将需要在每次使用该密钥时提供它(除非您正在运行存储解密密钥的 SSH 代理软件)。我们建议使用密码短语,但如果您不想设置密码短语,可以按 ENTER
跳过此提示。
[本地环境] 您的标识已保存在 /home/username/.ssh/id_rsa。 您的公钥已保存在 /home/username/.ssh/id_rsa.pub。 密钥指纹为: SHA256:CAjsV9M/tt5skazroTc1ZRGCBz+kGtYUIPhRvvZJYBs username@hostname 密钥的随机艺术图像为: +---[RSA 3072]----+ |o ..oo.++o .. | | o o +o.o.+... | |. . + oE.o.o . | | . . oo.B+ .o | | . .=S.+ + | | . o..* | | .+= o | | .=.+ | | .oo+ | +----[SHA256]-----+
现在您有了可以用于身份验证的公钥和私钥。下一步是将公钥放在您的服务器上,以便您可以使用 SSH 密钥身份验证登录。
步骤 2 —— 将 SSH 公钥复制到您的服务器
有多种方法可以将您的公钥上传到远程 SSH 服务器。您使用的方法在很大程度上取决于您可用的工具和当前配置的细节。
以下方法都会产生相同的最终结果。最简单、最自动化的方法首先描述,其后的方法都需要额外的手动步骤。如果可以使用前面的方法,则应该遵循这些方法。
使用 ssh-copy-id
复制您的公钥
将公钥复制到现有服务器的最简单方法是使用一个名为 ssh-copy-id
的实用程序。由于其简单性,如果可用,建议使用此方法。
ssh-copy-id
工具包含在许多发行版的 OpenSSH 软件包中,因此您的本地系统上可能已经有它。为使此方法工作,您必须当前具有基于密码的 SSH 访问权限到您的服务器。
要使用此实用程序,您需要指定您想要连接到的远程主机和您具有基于密码的 SSH 访问权限的用户帐户。这是您的公共 SSH 密钥将被复制的帐户。
语法是:
[本地环境] ssh-copy-id username@remote_host
您可能会看到类似以下的消息:
[本地环境] The 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
密钥。当它找到密钥时,它将提示您输入远程用户帐户的密码:
[本地环境] /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
的文件中。
您将看到以下输出:
[本地环境] Number 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"
您可能会看到类似以下的消息:
[本地环境] The 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
继续。
之后,您将被提示输入您尝试连接的帐户的密码:
[本地环境] username@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 的控制台。
一旦您可以访问远程服务器上的帐户,您应该确保 ~/.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
如果这是您第一次连接到此主机(如果您使用了上述最后一种方法),您可能会看到类似以下内容:
[本地环境] The 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 会话。
如果成功,继续了解如何锁定服务器。
第四步 — 在服务器上禁用密码身份验证
如果你能够使用 SSH 无需密码登录到你的账户,那么你已经成功地为你的账户配置了基于 SSH 密钥的身份验证。然而,你的基于密码的身份验证机制仍然是激活状态,这意味着你的服务器仍然容易受到暴力破解攻击。
在完成本节中的步骤之前,请确保你的服务器上要么已经为 root 账户配置了基于 SSH 密钥的身份验证,或者更好的是,你已经为服务器上具有 sudo
权限的账户配置了基于 SSH 密钥的身份验证。这一步将禁用基于密码的登录,因此确保你仍然能够获得管理员访问权限是至关重要的。
一旦上述条件为真,请使用 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 基础指南。