原文发表于:如何在 linux 服务器上配置基于 SSH 密钥的身份验证
SSH 是用于管理与服务器通信的加密协议。当你使用 Linux 服务器时,你的大部分时间有可能都花费在通过 SSH 连接到服务器的终端会话中。
尽管有许多不同的通过 SSH 登录服务器的方法,但在这篇文章中,我们将重点介绍 SSH 密钥方式。 SSH 密钥提供了一种简单,但极其安全的登录服务器的方法,这是我们向所有用户推荐的方法。
SSH 服务器可以使用许多不同的方法来验证客户端。其中最基本的是密码认证,这易于使用,但不是最安全的。
尽管密码是以安全的方式发送到服务器,但是它们通常不够复杂或者不够长,难以抵抗重复的,持久的攻击者。尽管有其他方法可以给密码认证额外添加一些安全性(fail2ban 等),但是 SSH 密钥的方式已经是一个可靠和安全的替代方法。
SSH 密钥对是两个加密的安全密码,可用于给 SSH 服务器验证客户端,每个密钥对由公钥和私钥组成。
私钥由客户端保留,应该保持绝对隐私。私钥一旦泄漏,攻击者就可以直接登录到相关联的公钥配置的服务器,而不需要额外的认证。而作为一个额外的保护措施,私钥可以用密码再次加密。
相关的公钥可以自由共享,没有任何负面后果。公钥可以用于加密只有私钥可以解密的消息。可以根据这个特性进行认证。
公钥被上传到你希望能够使用 SSH 登录的远程服务器。该密钥将添加到你用于登录的用户帐户目录下 ~/.ssh/authorized_keys
文件中
当客户端尝试使用 SSH 密钥进行身份验证时,服务器可以测试客户端是否拥有私钥。如果客户端可以证明它拥有私钥,则生成一个终端会话或执行请求的命令。
基本流程如图所示:
图中表示的是笔记本电脑连接到服务器,但它也可以认为一个服务器连接到另一个服务器。
要为服务器配置基于 SSH 密钥的身份验证,第一步是在本地计算机上生成 SSH 密钥对。
为此,我们可以使用 ssh-keygen
命令,它就包含在标准的 OpenSSH 工具套件中。默认情况下,它会创建一个 2048 位的 RSA 密钥对,大多数情况这就足够了。
在本地计算机上,通过输入以下命令生成 SSH 密钥对:
ssh-keygenGenerating 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 密钥。如果不想使用默认路径,可以现在输入。
如果你先前已经生成过 SSH 密钥对,可能会看到类似如下的提示:
/home/username/.ssh/id_rsa already exists.Overwrite (y/n)?如果你选择覆盖,你就无法使用之前的密钥进行身份验证。所以选择 “y” 时要非常小心,因为这是一个不可逆转的过程。
Created directory '/home/username/.ssh'.Enter passphrase (empty for no passphrase):Enter same passphrase again: 接下来,系统会提示你输入密钥的密码,这可用于加密硬盘上的私钥文件。
这时候你可能想知道如果你还是需要输入密码,那 SSH 密钥到底有什么优势。下面列出了一些:
SSH 私钥(可以密码保护的部分)永远不会暴露在网络上。密码仅用于解密本地机器上的密钥。这意味着无法针对私钥密码使用基于网络的暴力破解。
私钥保存在受限目录中,SSH 客户端不会识别未保存在受限目录中的私钥。密钥本身也必须具有受限权限(只能所有者读写),这表示系统上的其他用户无法窥探。
任何希望破解 SSH 私钥密码的攻击者都必须已经可以访问系统,这意味着他们已经可以访问您的用户帐户或 root 帐户。如果您处于这种状况下,密码可以防止攻击者立即登录到其他服务器,这样你就有时间创建和部署一个新的 SSH 密钥对,并移除受攻击的密钥的访问。
因为私钥永远不会暴露在网络中并且通过文件权限来保护,因此除了你(和 root 用户)之外的任何人都不能够访问此文件。私钥密码则在这些条件都被破坏的情况下作为额外的保护。
私钥密码是可选的,如果设置了,你就必须在每次使用此密钥时提供(除非您使用了存储解密密钥的 SSH 代理软件)。我们建议使用私钥密码,但如果您不想设置,只需按确认键跳过此提示。
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_hostThe key's randomart image is:+--[ RSA 2048]----+| ..o || E o= . || o. o || .. || ..S || o o. || =o.+. ||. =++.. ||o=++. |+-----------------+您现在有了一个公钥和一个私钥,您可以使用它来进行身份验证。下一步则是将公钥放到服务器上,以便可以使用 SSH 密钥身份验证登录。
如何把公钥拷贝到服务器上
如果你已经有一个可用服务器,你可以上传你的公钥,并使用它来验证。
你可以使用的方法取决于你可用的工具和当前配置。以下方法都会得到相同的结果,第一个是最简单,最自动化的方法,如果你无法使用前面的方法,那么之后的方法都需要额外的手动步骤。
使用 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”,然后按确认键继续。
接下来,程序将扫描你本地帐户下的 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 keysusername@111.111.11.111's passWord:输入密码(出于安全考虑,你的输入内容不会显示出来),然后按确认键。该程序将使用你提供的密码连接到远程主机上的帐户,然后把 ~/.ssh/id_rsa.pub
的内容,加入到远程帐户的 ~/.ssh/authorized_keys
文件中。
你会看到如下的输出:
Number of key(s) added: 1Now 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”,然后按确认键继续。
之后,系统会提示你输入尝试连接到的帐户的密码:
username@111.111.11.111's password:输入密码后,你的 id_rsa.pub
的内容就被复制到远程用户帐户的 authorized_keys
文件的末尾。
手动复制公钥
如果你不能通过基于密码的 SSH 访问服务器,那你必须手动完成上述操作。
你本地 ~/.ssh/id_rsa.pub
的内容必须添加到服务器上的 ~/.ssh/authorized_keys
文件中。
显示你本地的 ~/.ssh/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然后使用你任何可用的方法访问远程主机。
一旦在远程服务器上访问了你的帐户后,你首先要确保已经创建了 ~/.ssh
目录。如果还没有,可以用如下命令创建:
mkdir -p ~/.ssh现在,你可以在此目录下创建或修改 authorized_keys 文件。您可以把 id_rsa.pub
的内容添加到 authorized_keys 文件的末尾,命令如下:
echo public_key_string >> ~/.ssh/authorized_keys在上面的命令中,使用之前显示出的公钥内容替换 public_key_string。合法的公钥应该以 ssh-rsa AAAA
开头。
如果这步成功了,你可以退出然后尝试使用不需要密码的 SSH 登录服务器。
基于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”,然后按确认键继续。
如果你没有为你的私钥设置密码,你就能立即登录。如果你在创建密钥时为私钥设置了密码,那现在需要输入私钥密码。这时候,就会创建新的终端会话。
成功之后,继续看如何禁用服务器密码验证。
在服务器上禁用密码验证
如果你可以直接使用 SSH 而不是账户密码登录服务器,这表示你已成功配置了基于 SSH 密钥的身份验证。但是,这时基于密码的身份验证机制依然可用,这表示你的服务器仍然暴露在暴力攻击之下。
在完成本节中的步骤之前,请确保你的服务器上的 root 帐户或者最好是具有 sudo 访问权的的帐户配置了基于 SSH 密钥的身份验证。此步骤将禁止基于密码的登录,因此确保你依然能够获得管理访问权限是非常重要的。
一旦上述条件都满足了,以 root 身份或使用具有 sudo 权限的帐户使用 SSH 密钥登录到远程服务器,打开 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 密钥的身份验证,所以你可以直接登录服务器而不需要提供帐户密码了。
新闻热点
疑难解答