如何在Linux服务器上配置SSH密钥验证

SSH或Secure Shell,是远程管理Linux服务器的最常见的方式。虽然守护进程允许基于密码的认证,露出一个受密码保护的帐户网络就可以打开你的服务器以强力攻击。在本指南中,我们将演示如何配置SSH密钥服务器,这是建议的身份验证方法。这些都是更攻击者难以解决,给您一个更安全的登录机制。

介绍

SSH或安全shell是用于管理和与服务器通信的加密协议。当使用Linux服务器时,很可能你将大部分时间花费在通过SSH连接到服务器的终端会话中。 尽管有几种不同的登录SSH服务器的方法,但在本指南中,我们将重点介绍设置SSH密钥。 SSH密钥提供了一种简单,但极其安全的登录服务器的方法。因此,这是我们向所有用户推荐的方法。

SSH密钥如何工作?

SSH服务器可以使用各种不同的方法验证客户端。其中最基本的是密码认证,这是易于使用,但不是最安全的。 尽管密码以安全的方式发送到服务器,但是它们通常不复杂或长到足以抵抗重复的,持久的攻击者。 现代处理能力与自动化脚本相结合,使得强制密码保护帐户成为可能。 虽然有增加额外的安全性(其他方法fail2ban等),SSH密钥被证明是一个可靠和安全的替代方案。 SSH密钥对是两个密码安全密钥,可用于向SSH服务器验证客户端。每个密钥对由公钥和私钥组成。 私钥由客户端保留,应该保持绝对秘密。对私钥的任何损害将允许攻击者登录到使用相关联的公钥配置的服务器,而不需要额外的认证。作为一个额外的预防措施,密钥可以用密码在磁盘上加密。 相关的公钥可以自由共享,没有任何负面后果。公钥可以被用于加密只有私钥可以解密的消息。该属性用作使用密钥对进行认证的方式。 公钥被上传到您希望能够使用SSH登录的远程服务器。关键是加入到你会被登录到所谓的用户帐户中的特定文件~/.ssh/authorized_keys 。 当客户端尝试使用SSH密钥进行身份验证时,服务器可以测试客户端是否拥有私钥。如果客户端可以证明它拥有私钥,则生成shell会话或执行请求的命令。 流程概述如图所示: SSH密钥认证流程 该图显示了连接到服务器的笔记本电脑,但它可以很容易地是一个服务器连接到另一个服务器。

如何创建SSH密钥

为服务器配置SSH密钥身份验证的第一步是在本地计算机上生成SSH密钥对。 要做到这一点,我们可以使用一个名为特殊的工具ssh-keygen ,它是包含在工具标准的OpenSSH套件。默认情况下,这将创建一个2048位的RSA密钥对,这对大多数用途是很好的。 在本地计算机上,通过键入以下命令生成SSH密钥对:
ssh-keygen
Generating 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密钥对,则可能会看到类似如下的提示:
/home/username/.ssh/id_rsa already exists.
Overwrite (y/n)?
如果您选择覆盖磁盘上的键,你将无法使用先前键再进行身份验证。选择“是”时要非常小心,因为这是一个不可逆转的破坏性过程。
Created directory '/home/username/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again: 
接下来,系统将提示您输入密钥的密码。这是可用于加密磁盘上的私钥文件的可选密码。 您可能想知道如果您仍然需要输入密码短语,SSH密钥提供了什么优点。一些优点是:
  • 私有SSH密钥(可以密码保护的部分)永远不会暴露在网络上。密码仅用于解密本地机器上的密钥。这意味着基于网络的暴力强制不可能针对密码短语。
  • 私钥保存在受限目录中。 SSH客户端将不会识别未保存在受限目录中的私钥。密钥本身也必须具有受限权限(读写只能用于所有者)。这意味着系统上的其他用户无法窥探。
  • 任何希望破解私有SSH密钥密码的攻击者都必须已经访问系统。这意味着他们已经可以访问您的用户帐户或root帐户。如果您处于此位置,密码可以防止攻击者立即登录到其他服务器。这将有希望给您时间创建和实施一个新的SSH密钥对,并从受到攻击的密钥中删除访问。
由于私钥永远不会暴露在网络中,并且通过文件权限受到保护,因此除了您(和root用户)之外的任何人都不应该访问此文件。密码短语在这些条件被破坏的情况下用作附加的保护层。 密码是可选的添加。如果输入一个,您将必须在每次使用此密钥时提供(除非您正在运行存储解密密钥的SSH代理软件)。我们建议使用密码,但如果您不想设置密码,只需按ENTER键绕过此提示。
Your 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:
a9:49:2e:2a:5e:33:3e:a9:de:4e:77:11:58:b6:90:26 username@remote_host
The key's randomart image is:
+--[ RSA 2048]----+
|     ..o         |
|   E o= .        |
|    o. o         |
|        ..       |
|      ..S        |
|     o o.        |
|   =o.+.         |
|. =++..          |
|o=++.            |
+-----------------+
您现在有一个公钥和私钥,您可以使用它来进行身份验证。下一步是将公钥放在服务器上,以便可以使用SSH密钥身份验证登录。

如何在创建服务器时嵌入公钥

如果您正在启动一个新的DigitalOcean服务器,您可以自动将您的SSH公钥嵌入您的新服务器的根帐户。 在Droplet创建页面的底部,有一个选项可以将SSH密钥添加到服务器: SSH密钥嵌入 如果您已经向DigitalOcean帐户添加了公钥文件,您将在此看到一个可选择的选项(在上面的示例中有两个现有键:“工作键”和“主键”)。要嵌入现有的键,只需点击它,它会突出显示。您可以在单个服务器上嵌入多个键: SSH密钥选择 如果您尚未将公开的SSH金钥上传到您的帐户,或者您想在帐户中新增金钥,请按一下[+新增SSH金钥]按钮。这将扩展到一个提示: SSH密钥提示 在“SSH密钥内容”框中,粘贴SSH公用密钥的内容。假设您使用上述方法生成密钥,您可以通过键入以下内容在本地计算机上获取您的公钥内容:
cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDNqqi1mHLnryb1FdbePrSZQdmXRZxGZbo0gTfglysq6KMNUNY2VhzmYN9JYW39yNtjhVxqfW6ewc+eHiL+IRRM1P5ecDAaL3V0ou6ecSurU+t9DR4114mzNJ5SqNxMgiJzbXdhR+j55GjfXdk0FyzxM3a5qpVcGZEXiAzGzhHytUV51+YGnuLGaZ37nebh3UlYC+KJev4MYIVww0tWmY+9GniRSQlgLLUQZ+FcBUjaqhwqVqsHe4F/woW1IHe7mfm63GXyBavVc+llrEzRbMO111MogZUcoWDI9w7UIm8ZOTnhJsk7jhJzG2GpSXZHmly/a/buFaaFnmfZ4MYPkgJD username@example.com
将此值全部粘贴到较大的框中。在“注释(可选)”框中,可以为密钥选择一个标签。这将在DigitalOcean界面中显示为键名称: SSH新密钥 当你创建你的Droplet,您选择的公共SSH密钥将被放置在~/.ssh/authorized_keys的root用户帐户的文件。这将允许您使用您的私钥从计算机登录服务器。

如何将公钥复制到服务器

如果您已经有一个可用的服务器,并且在创建时没有嵌入密钥,您仍然可以上传您的公钥,并使用它来验证您的服务器。 使用的方法在很大程度上取决于您可用的工具和当前配置的详细信息。以下方法都会产生相同的最终结果。最简单,最自动化的方法是第一,如果您无法使用前面的方法,那么每个方法都需要额外的手动步骤。

使用SSH-Copy-ID复制公钥

你的公钥复制到现有服务器的最简单方法是使用一个工具,叫做ssh-copy-id 。由于其简单性,如果可用,建议使用此方法。 在ssh-copy-id工具包含在许多发行OpenSSH的包,所以你可能有它可在本地系统上。要使此方法起作用,您必须已经具有基于密码的SSH访问您的服务器。 要使用该实用程序,您只需要指定要连接到的远程主机和您有密码SSH访问的用户帐户。这是您的公共SSH密钥将被复制的帐户。 语法是:
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
这只是意味着您的本地计算机不能识别远程主机。这将在您第一次连接到新主机时发生。键入“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@111.111.11.111'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@111.111.11.111'"
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 '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”,然后按ENTER键继续。 之后,系统会提示您尝试连接到的帐户的密码:
username@111.111.11.111'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== demo@test
使用您可用的任何方法访问远程主机。例如,如果您的服务器是DigitalOcean Droplet,您可以使用控制面板中的Web控制台登录: 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密钥对您的服务器进行身份验证

如果您已成功完成的步骤之一上面,你应该能够登录到没有远程帐户的密码远程主机。 基本过程是一样的:
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”,然后按ENTER键继续。 如果您没有为您的私钥提供密码,您将立即登录。如果您在创建密钥时为私钥提供了密码,则需要立即输入密钥。然后,应该为远程系统上的帐户生成一个新的shell会话。 如果成功,继续找到如何锁定服务器。

在服务器上禁用密码验证

如果您能够使用SSH而不使用密码登录您的帐户,则表示您已成功为您的帐户配置了基于SSH密钥的身份验证。但是,您的基于密码的身份验证机制仍处于活动状态,这意味着您的服务器仍然暴露在强力攻击之下。 在完成本节的步骤之前,请确保您可能已配置基于SSH密钥的验证root帐户在该服务器上,或最好,你必须为此服务器配置有一个帐户基于SSH密钥的认证sudo访问。此步骤将锁定基于密码的登录,因此确保您仍然能够获得管理访问权限是至关重要的。 一旦上述条件为真,登录到您使用SSH密钥远程服务器,无论是作为根或与帐户sudo权限。打开SSH守护程序的配置文件:
sudo nano /etc/ssh/sshd_config
里面的文件,搜索名为指令PasswordAuthentication 。这可以注释掉。取消注释该行并将值设置为“no”。这将禁用您使用帐户密码通过SSH登录的能力:
PasswordAuthentication no
保存并在完成后关闭文件。要实际实施刚刚所做的更改,您必须重新启动服务。 在Ubuntu或Debian计算机上,您可以发出以下命令:
sudo service ssh restart
在CentOS / Fedora的机器,该程序被称为sshd
sudo service sshd restart
完成此步骤后,您已成功将SSH守护程序转换为仅响应SSH密钥。

结论

您现在应该已在服务器上配置并运行基于SSH密钥的身份验证,从而允许您在不提供帐户密码的情况下登录。从这里,有很多方向可以去。如果您想了解更多有关SSH的工作,看看我们的SSH要点指南