SSH 公钥登录以及多证书管理
SSH 公钥登录以及一些问题的笔记
生成密钥对
在服务器上生成用于登录的公钥和私钥,最终公钥放于服务器,私钥自己保存使用。
1 | $ ssh-keygen -t rsa |
首先提示输入生成文件的输出路径,然后是密码,最后是确认密码
密码是用于加密和登录时输入的密码,额,建议为空,不然还叫免密登录吗,但是请确保生成证书的安全,证书泄露可能很危险
生产环境强烈建议设置密码,毕竟稳定压倒一切,相当于双重验证吧,需要提供私钥,还要提供密码
导入公钥
1 | $ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys |
配置文件、文件夹的权限
1 | $ sudo chmod -R 0700 ~/.ssh |
SELinux
如果启用了 SELinux,还需要执行(root 用户把 /home 改成 /root)
1 | $ restorecon -R -v /home |
修改 SSH 配置文件
修改 SSH 配置文件,支持使用证书登录,修改该文件需要 root 权限。
找到并修改 /etc/ssh/sshd_config
文件下面的这些配置项:
1 | RSAAuthentication yes #RSA验证方式 |
随后重启 SSH 服务:
1 | systemctl restart sshd |
获取私钥
客户端获取私钥,可以使用 scp 或者其它方式:
1 | $ scp guan@192.168.1.2:~/.ssh/rsa ./ |
需要注意的是,在 windows 环境下,不要直接复制粘贴密钥对,这会使其失效。
前面修改了 SSH 配置,并且你恰好禁止的密码登录,此时你可能无法顺利拿到私钥,即:
1 | PasswordAuthentication no #是否允许通过密码登录 |
你可以先将这一项改为 yes,后续再修改回来。
使用私钥
拿到私钥后,不同客户端使用私钥的方式有所不同,不过其原理都是相同的。
PuTTY
生成证书
可以使用 PuTTY Key Generator 生成适用于 Putty 的证书
选中私钥文件,然后点击保存为私钥 Save private key
使用证书
- 打开Putty,加载或者新建一个会话
- 点击
connection
->data
, 输入Auto-login username
(自动登录的用户名) connection
->ssh
->auth
在Private key file for authentication
选择私钥文件保存会话
,然后直接点击会话即可免密登录
sh
对于各种 shell 环境,直接将私钥复制到 ~/.ssh/
下,命名为 id_rsa
即可。
1 | $ cp id_rsa ~/.ssh/id_rsa |
然后便可以直接进行 ssh 登录:
1 | $ ssh guan@192.168.1.2 |
公钥部署到多个服务器
再提醒一下,客户端使用私钥,服务端使用公钥。
将一份公钥部署到多个服务器,并正确配置,可以使用实现一份私钥免密登录到多个服务器上。当然这相当于将鸡蛋都装到了一个篮子里,安全风险也更大一些。
我们可以直接在多个服务器之间使用 scp 传输公钥:
1 | ssh user@host 'mkdir -p .ssh && cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub |
需要注意的是,不要直接复制粘贴公钥,很可能出错,导致服务器拒绝登录,特别是 windows 环境下
SSH 登录慢的问题
原因
OpenSSH 在用户登录的时候会验证 IP,它根据用户的 IP 使用反向 DNS 找到主机名,再使用 DNS 找到 IP 地址,最后匹配一下登录的 IP 是否合法。
如果客户机的 IP 没有域名,或者 DNS 服务器很慢或不通,会一直等到DNS超时,SSH 登录慢就体现在这里。
解决方法
修改 ssh 的配置文件,关闭 DNS 和 GSSAPI 验证即可加快登陆速度。
编辑 OpenSSH 的主配置文件 /etc/ssh/sshd_config
,找到并修改下面两个配置项
1 | GSSAPIAuthentication no |
然后重启 SSH 服务,再尝试登录测试一下是否有效。
1 | $ systemctl restart sshd |
再尝试登录测试一下是否有效。
多证书管理
前面说到了通过证书进行 SSH 免密登录,但在管理多个私钥的时候又有了新的问题。
在只有一份密钥对的时候,将公钥放在服务器上,并配置好 SSH,客户端将私钥保存为 ~/.ssh/id_rsa
即可进行免密登录,这个过程叫做 公钥登录
。例如:
1 | $ ssh root@192.168.1.1 |
但是,当拥有多个密钥对时,如何使用呢?
实际上,我们可以通过 -i
参数,指定要使用的私钥,这样就可以使用多个私钥了。例如:
1 | $ ssh -i ~/.ssh/id_local root@192.168.1.1 |
-i:identity_file,该参数指定要使用的证书。
之所以前面我们不指定该参数,也可以进行免密登录,是因为 ssh 默认会尝试并使用 ~/.ssh
目录下的几个证书(id_ecdsa、id_ed25519、id_rsa 等),如果存在且可用的话则使用,否则会提示输入密码。
config
虽然我们可以通过 -i 指定私钥,但随着数量增多,还是存在一些不便。此时我们可以通过配置 config
文件,来为不同主机配置不同的私钥,而无需每次都指定。
此外,还可以为主机配置别名,免去记不住 IP 地址的烦恼:
1 | Host host1 |
Host
相当于别名,可以通过该值替代 HostName
IdentityFile
不是必须的,不指定则相当于口令方式登录。