SSH 密钥解释

2025-06-07

SSH 密钥解释

最初发表于https://www.rittmanmead.com/,经许可在此转载。


SSH 密钥有什么用处?

您可以使用 创建一对密钥ssh-keygen。它们是纯文本
,可以根据需要进行剪切、粘贴和复制。其中一个是私有的
(例如id_rsa),您需要像保护其他
安全工具(例如服务器密码)一样保护它,并且您可以选择
使用密码短语进行保护。另一个是公开的(例如
id_rsa.pub),您可以与任何人共享。

您的公钥
由 服务器管理员放置在您需要访问的任何服务器上。它需要放在 用户主文件夹.ssh中名为 的文件中 此文件中可以放置任意数量的公钥。不要忘记 前面的点
authorized_keys

.ssh

SSH 密钥为何有用?

  • 您不需要密码即可登录服务器,这可以节省大量时间并提高工作效率。
  • 身份验证变成了“这是可以访问某些东西”而不是“这是访问它的代码,但我们不知道谁知道它”。
  • 它消除了共享服务器密码的需要
    • 更好的安全实践
    • 更轻松地审核究竟谁使用了服务器
  • 它能够授予对服务器的临时访问权限,并精确控制何时撤销访问权限以及撤销对象。
  • 私钥可以用密码保护,没有密码就无法使用。
  • 使用 SSH 密钥来控制服务器访问更加安全,因为您可以完全禁用服务器密码登录,从而杜绝任何暴力攻击的可能性
  • SSH 密钥可用于支持服务器之间的自动连接,以进行备份、启动作业等,而无需以纯文本形式存储密码

尖端

  • SSH 密钥只是纯文本,因此很容易在密码管理器(如LastPassKeePass1Password )中备份。
  • SSH 密钥在 Windows 系统中运行良好。PuTTY 和 WinSCP 等工具都支持它们,不过您需要先使用 PuTTYGen(一款辅助 PuTTY 工具)更改私钥的格式ppk
  • 虽然 SSH 密钥默认位于您的用户主.ssh文件夹中,但您
    可以将它们存储在 Dropbox 等云服务上,然后
    在任何您想要的机器上使用它们。

    • 要使用不在默认位置的密钥建立 ssh 连接
      ,请使用-i标志,例如

      ssh -i ~/Dropbox/ssh-keys/mykey foo@bar.com
      
  • 要查看有关设置 SSH 密钥的更多信息,请输入:

    man ssh
    
  • authorized_keys文件以空格分隔,每行的最后一项
    可以作为注释。注释通常默认为
    生成密钥的用户名和主机名,但也可以自由输入文本,以便
    根据需要更清晰地识别密钥。请参阅man sshd了解
    该文件的完整规范。

    SSH4

设置 SSH 密钥

使用 SSH 密钥需要从一对密钥中取出公钥,并将
其添加到另一台机器上,以便允许该密钥对的
私钥所有者访问该机器。我们这里要做的是
生成一个唯一的密钥对,用作整个
集群的身份标识。因此,每个节点都会拥有一份私钥副本以便能够
向任何其他节点进行身份验证,而其他节点也持有公钥副本
以及相同的私钥

在这个例子中,我将使用我自己的客户端机器连接到集群。如果本地 机器不合适,
你也可以轻松使用任何集群节点。

SSH 密钥策略

我们有几种方法可以实现 SSH 密钥。因为它是一个纯沙盒集群,所以我 也可以在我的机器上使用为集群生成的
相同 SSH 密钥对,因此相同的公钥/私钥 对会这样分发:

如果我们想要更高的安全性,更好的方法可能是将
我的个人 SSH 密钥的公钥也分发到整个集群中,而
只使用集群的私钥来真正标识集群节点。
这种方法的另一个好处是,客户端无需
持有集群 SSH 私钥的副本,只需
继续使用自己的私钥即可。

为了完整性,密钥策略的极端版本​​是
每台机器都有自己的 ssh 密钥对(即自己的安全
身份),并将相应的公钥分发给
集群中的其他节点:

但无论如何,这里我们使用第二个选项 -
在整个集群中使用唯一的密钥对,并且客户端的公共 ssh 密钥
也分布在整个集群中。

生成 SSH 密钥对

首先,我们需要生成密钥。我先创建一个文件夹来保存
它,因为我们一会儿要把它和
其他几个文件推送到集群中的所有服务器,而最简单的方法是
从单个文件夹执行此操作。

mkdir /tmp/rnmcluster02-ssh-keys
Enter fullscreen mode Exit fullscreen mode

请注意,在ssh-keygen下面的命令中,我使用参数指定
密钥的目标路径-f;如果您不这样做,请注意
不要意外地在默认
路径中覆盖您自己的密钥对~/.ssh

这些-q -N ""标志指示密钥生成过程不使用
密码短语,也不提示输入密码。这是最省力的
方法(使用前无需使用密码短语解锁 SSH 密钥
),但也是最不安全的。如果您要设置对
安全性至关重要的计算机的访问权限,请记住,如果
SSH 密钥上没有密码短语,则任何获得该密钥的人都可以访问任何
已授予该密钥访问权限的计算机(即已部署其公钥的计算机
)。

ssh-keygen -f /tmp/rnmcluster02-ssh-keys/id_rsa -q -N ""
Enter fullscreen mode Exit fullscreen mode

这会在tmp文件夹中生成两个文件 - 一对私钥和公钥
.pub):

robin@RNMMBP ~ $ ls -l /tmp/rnmcluster02-ssh-keys
total 16
-rw-------  1 robin  wheel  1675 30 Nov 17:28 id_rsa
-rw-r--r--  1 robin  wheel   400 30 Nov 17:28 id_rsa.pub
Enter fullscreen mode Exit fullscreen mode

准备authorized_keys文件

现在,我们将准备一个authorized_keys文件,该文件用于
存储任何允许访问该计算机的身份的 SSH 公钥。请注意
计算机上的每个用户authorized_keys都有自己的文件,位于 中
~/.ssh/。例如,root 用户的文件位于 中
/root/.ssh/authorized_keys,并且该文件中列出的任何公钥都可以以 root 用户身份
连接到服务器。请注意 “authorized”的美式拼写错误——正确拼写为 “authorised”不会出现任何明显的错误,但 ssh 密钥 登录也将无法正常工作。



因此,我们将刚刚为集群创建的唯一公钥对复制到authorized_keys文件中。此外,我们
还需要复制我们自己的个人 ssh 密钥(以及我们
想要授予集群中所有节点访问权限的任何其他公钥):

cp /tmp/rnmcluster02-ssh-keys/id_rsa.pub /tmp/rnmcluster02-ssh-keys/authorized_keys
# [optional] Now add any other keys (such as your own) into the authorized_keys file just created
cat ~/.ssh/id_rsa.pub >> /tmp/rnmcluster02-ssh-keys/authorized_keys
# NB make sure the previous step is a double >> not > since the double appends to the file, a single overwrites.
Enter fullscreen mode Exit fullscreen mode

分发 SSH 工件

现在,我们将把这组 SSH 文件推送到 每个节点上目标用户的.ssh文件夹中,在本例中是 root 用户。 从安全角度来看,最好使用非 root 用户登录,然后根据需要使用 sudo,但我们首先要保持 简单(安全性也较低)。因此,我们 文件夹中的文件如下:




  • id_rsa--密钥对的私钥
  • id_rsa.pub——密钥对的公钥。严格来说,这不需要分发到所有节点,但将其与私钥一起保存是常规且方便的做法。
  • authorized_keys——这是每个节点上的sshd守护进程将查看的文件,以验证传入的登录请求提供的私钥,因此需要保存允许以此用户身份访问机器的任何人的公钥。

要复制文件,我们将使用scp,但如何将它们放到位
并不重要,只要它们到达正确的位置即可:

scp -r /tmp/rnmcluster02-ssh-keys root@rnmcluster02-node01:~/.ssh
Enter fullscreen mode Exit fullscreen mode

此时,您需要输入目标用户的密码,但
别担心!这是您最后一次输入密码,因为后续
登录将使用您现在配置的 ssh 密钥进行身份验证

对集群中的所有节点运行 scp 命令。如果集群中有四个节点,
则输出应该如下所示:

$ scp -r /tmp/rnmcluster02-ssh-keys/ root@rnmcluster02-node01:~/.ssh
root@rnmcluster02-node01's password:
authorized_keys                                                  100%  781     0.8KB/s   00:00
id_rsa                                                           100% 1675     1.6KB/s   00:00
id_rsa.pub                                                       100%  400     0.4KB/s   00:00
$ scp -r /tmp/rnmcluster02-ssh-keys/ root@rnmcluster02-node02:~/.ssh
Warning: Permanently added the RSA host key for IP address '172.28.128.7' to the list of known hosts.
root@rnmcluster02-node02's password:
authorized_keys                                                  100%  781     0.8KB/s   00:00
id_rsa                                                           100% 1675     1.6KB/s   00:00
id_rsa.pub                                                       100%  400     0.4KB/s   00:00
$ scp -r /tmp/rnmcluster02-ssh-keys/ root@rnmcluster02-node03:~/.ssh
root@rnmcluster02-node03's password:
authorized_keys                                                  100%  781     0.8KB/s   00:00
id_rsa                                                           100% 1675     1.6KB/s   00:00
id_rsa.pub                                                       100%  400     0.4KB/s   00:00
$ scp -r /tmp/rnmcluster02-ssh-keys/ root@rnmcluster02-node04:~/.ssh
root@rnmcluster02-node04's password:
authorized_keys                                                  100%  781     0.8KB/s   00:00
id_rsa                                                           100% 1675     1.6KB/s   00:00
id_rsa.pub                                                       100%  400     0.4KB/s   00:00
Enter fullscreen mode Exit fullscreen mode

测试通过 SSH 密钥验证的登录

关键时刻到了。从你的客户端机器,尝试通过 SSH 连接到每个
集群节点。如果提示你输入密码,则说明出现了问题
——请参阅下面的故障排除部分。

authorized_keys如果您在创建时输入了自己的公钥,
那么您不需要指定连接时要使用的密钥,因为
它默认会使用您自己的私钥:

robin@RNMMBP ~ $ ssh root@rnmcluster02-node01
Last login: Fri Nov 28 17:13:23 2014 from 172.28.128.1



[root@localhost ~]#
Enter fullscreen mode Exit fullscreen mode

好了——自动登录,无需输入密码。如果我们
使用的是集群的私钥(而不是我们自己的),则需要在连接时
指定它。-i

robin@RNMMBP ~ $ ssh -i /tmp/rnmcluster02-ssh-keys/id_rsa root@rnmcluster02-node01
Last login: Fri Nov 28 17:13:23 2014 from 172.28.128.1



[root@localhost ~]#
Enter fullscreen mode Exit fullscreen mode

SSH 密钥连接故障排除

SSH 密钥是系统管理员工具箱里最有用的工具之一,但一旦
出现问题,找回密钥就会变得有点棘手。首先要
检查的是,目标机器上authorized_keys执行
所有操作的文件(列出允许连接
到指定用户的主机的 SSH 密钥)是否已安装到位:

[root@localhost .ssh]# ls -l ~/.ssh/authorized_keys
-rw-r--r-- 1 root root 775 Nov 30 18:55 /root/.ssh/authorized_keys
Enter fullscreen mode Exit fullscreen mode

如果你收到这个:

[root@localhost .ssh]# ls -l ~/.ssh/authorized_keys
ls: cannot access /root/.ssh/authorized_keys: No such file or directory
Enter fullscreen mode Exit fullscreen mode

那么你就有问题了。

在这个特定情况下,一个可能的问题是,上述
预设scp假设用户的.ssh文件夹尚不
存在
(因为在全新的服务器上确实不存在),因此将其指定为
整个rnmcluster02-ssh-keys文件夹的目标名称。然而,如果
文件夹确实已存在,则最终会将该
rnmcluster02-ssh-keys文件夹复制.ssh文件夹​​中:

[root@localhost .ssh]# ls -lR
.:
total 12
-rw------- 1 root root 1675 Nov 22  2013 id_rsa
-rw-r--r-- 1 root root  394 Nov 22  2013 id_rsa.pub
drwxr-xr-x 2 root root 4096 Nov 30 18:49 rnmcluster02-ssh-keys

./rnmcluster02-ssh-keys:
total 12
-rw-r--r-- 1 root root  775 Nov 30 18:49 authorized_keys
-rw------- 1 root root 1675 Nov 30 18:49 id_rsa
-rw-r--r-- 1 root root  394 Nov 30 18:49 id_rsa.pub
[root@localhost .ssh]#
Enter fullscreen mode Exit fullscreen mode

要修复此问题,只需将其authorized_keys
rnmcluster02-ssh-keys.ssh

[root@localhost .ssh]# mv ~/.ssh/rnmcluster02-ssh-keys/authorized_keys ~/.ssh/
Enter fullscreen mode Exit fullscreen mode

其他常见的问题原因是
目标用户.ssh文件夹的文件/文件夹权限太松(可以使用 修复
chmod -R 700 ~/.ssh),或者连接用户的 ssh 私钥(修复方式:
chmod 600 id_rsa)。后者会在连接尝试时
清晰地显示:

robin@RNMMBP ~ $ ssh -i /tmp/rnmcluster02-ssh-keys/id_rsa root@rnmcluster02-node01
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0777 for '/tmp/rnmcluster02-ssh-keys/id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: /tmp/rnmcluster02-ssh-keys/id_rsa
Enter fullscreen mode Exit fullscreen mode

另一个困扰我两次的问题——
我稍后会演示如何进行故障排除——是SELinux在使用 ssh 密钥
进行 root 访问时会变得很棘手
。我总是
把它当作一个方便的提醒,提醒我禁用 selinux(在
/etc/selinux/config,set SELINUX=disabled),因为我从来没有理由
让它一直处于启用状态。但是,如果你确实需要启用它,你需要访问
互联网来查找此问题的确切原因/解决方案。

因此,要解决 SSH 密钥问题,通常需要做两件事。首先
,从客户端指定详细程度(对于大多数情况来说-v,稍微详细一点
-vvv

ssh -v -i /tmp/rnmcluster02-ssh-keys/id_rsa root@rnmcluster02-node01
Enter fullscreen mode Exit fullscreen mode

您应该观察 ssh 尝试使用私钥,如果服务器
拒绝它,它将回退到它能找到的任何其他 ssh 私钥,
然后进行密码验证:

[...]
debug1: Offering RSA public key: /tmp/rnmcluster02-ssh-keys/id_rsa
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug1: Next authentication method: password
Enter fullscreen mode Exit fullscreen mode

问题通常出在服务器端,因此假设您
仍然可以连接到服务器(例如通过物理控制台或
使用密码验证),然后检查所有与尝试连接相关的/var/log/secure日志
。以下是与上述客户端日志对应的日志
文件,其中尝试了 ssh 密钥验证
但失败,然后使用密码验证
成功连接:

Nov 30 18:15:05 localhost sshd[13156]: Authentication refused: bad ownership or modes for file /root/.ssh/authorized_keys
Nov 30 18:15:15 localhost sshd[13156]: Accepted password for root from 172.28.128.1 port 59305 ssh2
Nov 30 18:15:15 localhost sshd[13156]: pam_unix(sshd:session): session opened for user root by (uid=0)
Enter fullscreen mode Exit fullscreen mode

现在我们可以清楚地看到问题是什么——“ 文件 /root/.ssh/authorized_keys 的所有权或模式错误
”。

故障排除的最后一步是让 sshd(
运行在我们尝试连接的主机上的 ssh 守护进程)发出更详细的
日志。您可以设置LogLevel DEBUG1(或 DEBUG2 或 DEBUG3)
/etc/ssh/sshd_config并重新启动 ssh 守护进程
service sshd restart),或者您也可以从主机运行第二个 ssh 守护进程
并指定特定的日志记录。这适用于
多用户服务器,因为您无法直接更改 sshd 的配置。
要运行第二个 sshd 实例,您可以使用:

/usr/sbin/sshd -D -d -p 2222
Enter fullscreen mode Exit fullscreen mode

您必须从绝对路径运行(如果 不这样做,sshd系统会提示您)。该标志会停止以守护进程运行,而是以 交互方式运行,以便我们可以轻松查看所有输出。 指定调试日志记录(更高级别的详细程度 ),并指示 sshd 监听端口 2222。由于我们是 在现有 sshd 之上执行此操作,因此显然不能使用 默认的 ssh 端口(22),因此请选择另一个可用的端口(并且没有 被防火墙阻止)。
-D
-d
-dd-ddd
-p 2222


现在在客户端重试连接,但指向交互式 sshd 实例的端口

ssh -v -p 2222 -i /tmp/rnmcluster02-ssh-keys/id_rsa root@rnmcluster02-node01
Enter fullscreen mode Exit fullscreen mode

当您在客户端上运行命令时,您应该同时获得客户端
和主机调试输出,以便您
进行大量诊断并分析 ssh 握手等,
以找到问题的根源。

文章来源:https://dev.to/rmoff/ssh-keys-explained-2e2l
PREV
OAuth入门指南
NEXT
强化暴露在互联网上的 Linux 服务器的 8 个措施