背景简介

获得了一个服务器的ssh的密钥登陆权限,不过,在linux下使用ssh命令登陆时出现错误。经过一番尝试后姑且算是解决了,在此将背景和过程予以记录。

  • 系统环境
客户端环境 服务端环境
运行系统 manjaro i3(2020-7-10版本) Ubuntu 18.04 bionic
openssh版本 8.3p1 7.6p1
openssl版本 1.1.1g 1.0.2n

载入密钥文件出错

报错信息

终端执行 ssh -i ~/.ssh/EXISTING.pem user@host ,尝试服务器管理员提供的密钥验证登陆时报错密钥格式无效。

  • 报错信息:

load pubkey “~/.ssh/EXISTING.pem”: invalid format
Received disconnect from [host] port 22:2: Too many authentication failures
Disconnected from [host] port 22

  • 管理员提供的密钥文件EXISTING.pem样例
1
2
3
4
5
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAs2osJSOIglNtWz9c3SAUIcfUKJdRwxl/oX3+2Cz8YkaCDdFz8iAB2GQ/CqUR
……………………(此处省略若干行)…………………………
k28506DFGnhd2U/FoWbNdPPAeSv8BpvCmlPsNoTePtIDOvFOFw9s4yufGuOCRIJ0HRwCqCI=
-----END RSA PRIVATE KEY-----

问题分析

经过资料的搜索,在archlinux关于ssh-key页面的wiki页面1找到了一个解决方案,可以使用 ssh-keygen -f ~/.ssh/id_rsa -p 命令来将旧版密码格式更新为新版密码格式。(这个命令一般用于在不更新实际密钥的情况下更新密钥密码短语)

推测可能是因为客户端的openssh相对服务端更新,导致旧版ssh-keygen生成的ssh密钥不再支持。

据archlinux关于ssh-key的wiki页面1所述,应该是由于旧版私钥密码的编码方式(md5)不够安全,于是自openssh6.5开始支持一种新的密钥格式,自openssh7.8开始,将这一新的私钥格式作为默认密钥格式。

(但是没查到openssh什么时候禁用了旧版的密钥格式)。

根据v2ex论坛的一个回复2所述,openssh于8.3版本开始禁止rsa+sha1密钥的使用。

解决方法

使用ssh-keygen命令更新密钥格式(以及密钥密码)

1
2
3
4
5
chmod 600 ~/.ssh/EXISTING.pem
ssh-keygen -f ~/.ssh/EXISTING.pem -p
   Enter new passphrase (empty for no passphrase): #设置密钥密码,无密码则为空
   Enter same passphrase again:                    #重复密码
   Your identification has been saved with the new passphrase. #更新完成的提示

更新后的密钥格式样例

1
2
3
4
5
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
……………………(此处省略若干行)…………………………
YJs8yacs62WnNGytAAAAAAEC
-----END OPENSSH PRIVATE KEY-----

如果只是因为密钥被禁用的话,到这里应该就算解决了。(或者干脆重新生成一个新的可用密钥上传到服务器上应该也可以?)

不过,遗憾的是,还有一个问题导致我依然无法登陆……

身份验证失败过多

报错信息

将新的证书文件复制到~/.ssh文件夹后,继续使用ssh尝试登陆服务器,不过这次又遇到了一个之前没有遇到过的新的问题——身份验证失败过多。

执行 ssh -i ~/.ssh/EXISTING.pem user@host -v 所输出的比较重要的一段日志(有一定删改处理)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
debug1: SSH2_MSG_NEWKEYS received
debug1: rekey in after 134217728 blocks
debug1: Will attempt key: user@user-pc RSA SHA256:F0khbvuw4 agent
debug1: Will attempt key: [email protected] RSA SHA256:i4orhwR8Hr018o agent
debug1: Will attempt key: [email protected] RSA SHA256:vVsRXg8 agent
debug1: Will attempt key: ~/.ssh/neoterm_rsa RSA SHA256:X3zbkysUxOexuo agent
debug1: Will attempt key: [email protected] ED25519 SHA256:pErpRYS3/6TUQ agent
debug1: Will attempt key: [email protected] ED25519 SHA256:FC2aJ+zc17bwGo agent
debug1: Will attempt key: ~/.ssh/EXISTING.pem  explicit
debug1: SSH2_MSG_EXT_INFO received
debug1: kex_input_ext_info: server-sig-algs=<ssh-ed25519,ssh-rsa,rsa-sha2-256,rsa-sha2-512,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521>
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Offering public key: user@user-pc RSA SHA256:F0khbvuw4 agent
debug1: Authentications that can continue: publickey
debug1: Offering public key: [email protected] RSA SHA256:nwR8Hr018o agent
debug1: Authentications that can continue: publickey
debug1: Offering public key: [email protected] RSA SHA256:G8nsRXg8 agent
debug1: Authentications that can continue: publickey
debug1: Offering public key: ~/.ssh/neoterm_rsa RSA SHA256:j1kysUxOexuo agent
debug1: Authentications that can continue: publickey
debug1: Offering public key: [email protected] ED25519 SHA256:pEpcomOUbpRYS3/6TUQ agent
debug1: Authentications that can continue: publickey
debug1: Offering public key: [email protected] ED25519 SHA256:F+h42aJ+zc17bwGo agent
Received disconnect from [ip] port 22:2: Too many authentication failures
Disconnected from [ip] port 22

这里的这个错误甚至影响到了我自己的vps服务器的正常登陆。

问题分析

通过日志发现,ssh在使用由‘-i’选项指定的密钥文件之前,试图使用一些其他密钥登陆,结果就在ssh使用由‘-i’选项指定的密钥登陆之前,就因为尝试次数过多而断开链接了……

而这些ssh密钥是通过ssh-add命令添加至ssh-agent的密钥,用于在克隆git存储库自动登陆git仓库(git托管提供商的教程中有记载)。为了方便,我直接在bashrc配置文件里加上了 ssh-add ~/.ssh/*key ,以自动加载密钥——然后这导致了bug。

ssh-agent会在每次链接之前先把加进ssh-agent去的密钥都试一遍,都失败了才去试密码或者其余密钥来验证(虽然感觉正常来说是应该先尝试手动指定的证书才对)。而以前的密钥数量比较少,所以没触发服务器验证失败过多的问题前就验证登陆成功了。但是,之前刚刚新配置了几个密钥,导致ssh-agent又多了几个需要试的密钥——于是“ ssh验证失败过多,断开链接。

解决方法

临时解决方法

如果服务器支持密码登陆,则可以使用 -o PreferredAuthentications=password -o PubkeyAuthentication=no 选项来临时禁用密钥登陆,强制使用密码。

正式解决方法

编辑~/.ssh/config,把域名相对固定的ssh服务的密钥配置记载进去

1
2
3
4
5
6
7
8
9
Host github.com
      Hostname github.com
      IdentityFile /home/user/.ssh/github_key
Host gitlab.com
      Hostname gitlab.com
      IdentityFile /home/user/.ssh/gitlab_key
Host bitbucket.org
      Hostname bitbucket.org
      IdentityFile /home/user/.ssh/bitbucket_key

对bashrc文件进行修改,注释掉一部分ssh-add载入密钥的命令。

最后,执行 ssh-add -D 删除密钥链所有已经加载了的密钥。

一切正常的话,现在可以使用ssh命令链接到ssh服务器了。

后记

同时遇到两个问题,排查问题好难呢……已经午夜了呢,好困。