关于SSH登录中 公钥指纹 科普

昨天公司 Git 服务器进行了升级 导致密钥全部都没了 需要重新上传 有个别几个项目顺便换了个地址

SSH 首次登陆

当重新上传SSH Key 然后设置完 Git 远端项目地址后 发现有个小提示信息 如下

$ git fetch
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:7g/bojcSbdVWBrfNrQ5+k+XQZuo4mp0V7MnUPD21nec.
Please contact your system administrator.
Add correct host key in /c/Users/reggie/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /c/Users/reggie/.ssh/known_hosts:2
ECDSA host key for [xxx.xxx.com]:12222 has changed and you have requested strict checking.
Host key verification failed.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

$ git fetch
The authenticity of host '[host]:12222 ([xxx.xxx.xx.xxx]:12222)' can't be established.
ECDSA key fingerprint is SHA256:7g/bojcSbdVWBrfNrQ5+k+XQZuo4mp0V7MnUPD21nec.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[host]:12222' (ECDSA) to the list of known hosts.
Warning: the ECDSA host key for '[host]:12222' differs from the key for the IP address '[121.201.57.228]:10022'
Offending key for IP in /c/Users/reggie/.ssh/known_hosts:7
Are you sure you want to continue connecting (yes/no)? yes

大概翻译下就是有可能有某人在服务器做了些 “坏事”
有人可能在窃听你(中间人攻击)
还可能更换了主机密钥
下面是主机发送的 公钥指纹 其值
SHA256:7g/bojcSbdVWBrfNrQ5+k+XQZuo4mp0V7MnUPD21nec.

发生的原因

找了下相关 known_hosts 内容 这个提示一般发生在第一次连接服务器的时候 SSH 会对进行连接的服务器核对你历史信息登录的服务器文件 也就是 known_hosts 文件

这个里面记录了你登录过的服务器信息 什么IP啦端口啦 还有最重要的 服务器的 公钥指纹 而本次我们换了Git服务器 公钥指纹也发生了变动 然后SSH在下面进行比对的时候发现不一致

给出提示 有可能会发生中间人攻击 问我们是否信任主机 同时还返回了服务器的 公钥指纹 我们可以校验服务器的 公钥指纹 已确认是否是我们需要真正连接的服务器 而不是中间人的服务器。

如果我们输入 yes 表示确认是正确的服务器 然后他会吧相关信息写入 到 known_hosts 文件 然后继续下面的连接。

后面还有一个小插曲 就是我输入了一个yes后 信息也写入了 但是每次连接还是会提示这个 后面我发现是Git服务器的域名没变 IP变了

然后上面一条记录是连接的老的服务器 而指纹已经变了,新的指纹信息在最下面。

推测应该是从上而下读取记录信息 然后比对的 比对到老的地址了 然后发现指纹不一致 直接弹了这个出来

后面我直接把 known_hosts 文件清空了 重新连接一次 OK 搞定

中间人攻击

SSH的首次连接会下载服务端的公钥,用户确认后公钥将被保存并信任。

下次访问时客户端将会核对服务端发来的公钥和本地保存的是否相同,不同就发出中间人攻击的警告拒绝连接,除非用户手动清除已保存的公钥。

所以,如果首次连接没有中间人,之后的连接就无需担心中间人,因为中间人给出的公钥和服务端给出的公钥相同的可能性可以忽略。

如果首次连接就有中间人攻击,那么恭喜你中奖了。

校验公钥指纹

关于上一步给出来的 服务器 公钥指纹如何校验 找了一圈内容 大概都没有好的办法来校验。

一般都是服务器端公开自己的密钥指纹 比如 Github 他们公开了自己的公钥指纹 然后连接的时候返回过来可以自己对比下是否一致。

还有一种校验方式操作如下

获取服务端公钥

$ ssh-keyscan -t ECDSA -p 22 host > xx.txt
# host:22 SSH xxxx

然后我们可以查看 xx.txt 文件(注意你的路径哈)

[host]:22 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBAv7EZMq4b//f0Wj1ik/GK8G1/YwwU4dpS2d3C6YuPY0lMHeivFW4OyWOADqi7wnlO3Ot6fVZ6t1hZjQqhj2u4=

这个内容其实和写入你的 known_hosts 的内容是一样的

校验公钥指纹

可以使用下面的命令来生成公钥指纹 -E 参数是指定指纹的类型 注意一开始返回的类型一致 上面是sha256

$ ssh-keygen -E sha256 -lf xx.txt
256 SHA256:7g/bojcSbdVWBrfNrQ5+k+XQZuo4mp0V7MnUPD21nec no comment (ECDSA)

可以看到返回的值是 SHA256:7g/bojcSbdVWBrfNrQ5+k+XQZuo4mp0V7MnUPD21nec 这和一开始第一次连接服务器时返回的指纹是一致的 SHA256:7g/bojcSbdVWBrfNrQ5+k+XQZuo4mp0V7MnUPD21nec。 这样就完成了一次校验 但是这个校验真的是准确的吗 如果你获取到的公钥都是 中间人的呢… 好吧我也不知道了!!! 一般都是服务器放公开自己的指纹 然后比对吧 这样靠谱点。

php
本作品采用《CC 协议》,转载必须注明作者和本文链接
微信公众号:码咚没 ( ID: codingdongmei )
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!