SSH 密钥解释
最初发表于https://www.rittmanmead.com/,经许可在此转载。
SSH 密钥有什么用处?
您可以使用 创建一对密钥ssh-keygen。它们是纯文本
,可以根据需要进行剪切、粘贴和复制。其中一个是私有的
(例如id_rsa),您需要像保护其他
安全工具(例如服务器密码)一样保护它,并且您可以选择
使用密码短语进行保护。另一个是公开的(例如id_rsa.pub),您可以与任何人共享。
您的公钥
由 服务器管理员放置在您需要访问的任何服务器上。它需要放在 用户主文件夹.ssh中名为 的文件中。 此文件中可以放置任意数量的公钥。不要忘记 前面的点。authorized_keys.ssh
SSH 密钥为何有用?
- 您不需要密码即可登录服务器,这可以节省大量时间并提高工作效率。
- 身份验证变成了“这是谁可以访问某些东西”而不是“这是访问它的代码,但我们不知道谁知道它”。
- 它消除了共享服务器密码的需要
- 更好的安全实践
- 更轻松地审核究竟谁使用了服务器
- 它能够授予对服务器的临时访问权限,并精确控制何时撤销访问权限以及撤销对象。
- 私钥可以用密码保护,没有密码就无法使用。
- 使用 SSH 密钥来控制服务器访问更加安全,因为您可以完全禁用服务器密码登录,从而杜绝任何暴力攻击的可能性
- SSH 密钥可用于支持服务器之间的自动连接,以进行备份、启动作业等,而无需以纯文本形式存储密码
尖端
- SSH 密钥只是纯文本,因此很容易在密码管理器(如LastPass、KeePass或1Password )中备份。
- 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了解
该文件的完整规范。
设置 SSH 密钥
使用 SSH 密钥需要从一对密钥中取出公钥,并将
其添加到另一台机器上,以便允许该密钥对的
私钥所有者访问该机器。我们这里要做的是
生成一个唯一的密钥对,用作整个
集群的身份标识。因此,每个节点都会拥有一份私钥副本,以便能够
向任何其他节点进行身份验证,而其他节点也持有公钥副本
(以及相同的私钥)。
在这个例子中,我将使用我自己的客户端机器连接到集群。如果本地 机器不合适,
你也可以轻松使用任何集群节点。
SSH 密钥策略
我们有几种方法可以实现 SSH 密钥。因为它是一个纯沙盒集群,所以我 也可以在我的机器上使用为集群生成的
相同 SSH 密钥对,因此相同的公钥/私钥 对会这样分发:
如果我们想要更高的安全性,更好的方法可能是将
我的个人 SSH 密钥的公钥也分发到整个集群中,而
只使用集群的私钥来真正标识集群节点。
这种方法的另一个好处是,客户端无需
持有集群 SSH 私钥的副本,只需
继续使用自己的私钥即可。
为了完整性,密钥策略的极端版本是
每台机器都有自己的 ssh 密钥对(即自己的安全
身份),并将相应的公钥分发给
集群中的其他节点:
但无论如何,这里我们使用第二个选项 -
在整个集群中使用唯一的密钥对,并且客户端的公共 ssh 密钥
也分布在整个集群中。
生成 SSH 密钥对
首先,我们需要生成密钥。我先创建一个文件夹来保存
它,因为我们一会儿要把它和
其他几个文件推送到集群中的所有服务器,而最简单的方法是
从单个文件夹执行此操作。
mkdir /tmp/rnmcluster02-ssh-keys
请注意,在ssh-keygen下面的命令中,我使用参数指定
密钥的目标路径-f;如果您不这样做,请注意
不要意外地在默认
路径中覆盖您自己的密钥对~/.ssh。
这些-q -N ""标志指示密钥生成过程不使用
密码短语,也不提示输入密码。这是最省力的
方法(使用前无需使用密码短语解锁 SSH 密钥
),但也是最不安全的。如果您要设置对
安全性至关重要的计算机的访问权限,请记住,如果
SSH 密钥上没有密码短语,则任何获得该密钥的人都可以访问任何
已授予该密钥访问权限的计算机(即已部署其公钥的计算机
)。
ssh-keygen -f /tmp/rnmcluster02-ssh-keys/id_rsa -q -N ""
这会在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
准备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.
分发 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
此时,您需要输入目标用户的密码,但
别担心!这是您最后一次输入密码,因为后续
登录将使用您现在配置的 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
测试通过 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 ~]#
好了——自动登录,无需输入密码。如果我们
使用的是集群的私钥(而不是我们自己的),则需要在连接时
指定它。-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 ~]#
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
如果你收到这个:
[root@localhost .ssh]# ls -l ~/.ssh/authorized_keys
ls: cannot access /root/.ssh/authorized_keys: No such file or directory
那么你就有问题了。
在这个特定情况下,一个可能的问题是,上述
预设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]#
要修复此问题,只需将其authorized_keys移rnmcluster02-ssh-keys回.ssh:
[root@localhost .ssh]# mv ~/.ssh/rnmcluster02-ssh-keys/authorized_keys ~/.ssh/
其他常见的问题原因是
目标用户.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
另一个困扰我两次的问题——
我稍后会演示如何进行故障排除——是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
您应该观察 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
问题通常出在服务器端,因此假设您
仍然可以连接到服务器(例如通过物理控制台或
使用密码验证),然后检查所有与尝试连接相关的/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)
现在我们可以清楚地看到问题是什么——“ 文件 /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
您必须从绝对路径运行(如果 不这样做,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
当您在客户端上运行命令时,您应该同时获得客户端
和主机调试输出,以便您
进行大量诊断并分析 ssh 握手等,
以找到问题的根源。
后端开发教程 - Java、Spring Boot 实战 - msg200.com







