SSH协议通过known host来减少受到中间人攻击(Man-in-the-Middle Attack)的可能性.我们这个案例是连接本机的ssh服务端,风险比较小.如果我们需要在一个复杂的网络环境中去连接一个远端的服务器,很可能会遭遇到中间人攻击,假如本机和远端机器间各种一个或者若干个局域网,中间可能还通过广域网,在这种情况下,黑客可以在网络中间设置一个欺诈服务器,伪装成我们要连接的远端服务器,我们就可能会连接上错误的服务器,或者所有的请求和响应都被它代理,失去SSH的加密特性.
SSH的公钥加密过程:
- 远程主机收到用户的登录请求,把自己的公钥发给用户.
- 用户使用这个公钥,将登录密码加密后,发送回来.
- 远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录.
如果我们连上黑客的伪服务器,它就可以把伪造的公钥发给我们,从而截获我们的密码.
当我们第一次连接ssh服务端时,会将服务端上的公钥指纹打印出来,用户需要检查下这个指纹是否是正确的,如果指纹不对,需要拒绝连接.为了能够鉴别出这个指纹,ssh服务端的管理员需要事先在网页/邮件/聊天工具中将这个指纹公告出来.
在上面的ssh连接案例中,我们可以看到ssh服务端ECDSA公钥的指纹的两种表达方式(SHA256/MD5)
ECDSA key fingerprint is SHA256:xRaqsG/D2EFWfKbv6Ke8ImjHXBpo3jZ3N1Xp0NVhJLg.
ECDSA key fingerprint is MD5:d1:36:75:6d:b2:da:9d:f9:5e:ea:01:3f:6e:66:aa:e2.
这与我们安装ssh服务端时看到的日志是一致的:
Your public key has been saved in /etc/ssh/ssh_host_ecdsa_key.pub.
The key fingerprint is:
SHA256:xRaqsG/D2EFWfKbv6Ke8ImjHXBpo3jZ3N1Xp0NVhJLg root@ssh_server
我们也可以用如下指令查看下ssh_host_ecdsa_key.pub的指纹:
[root@ssh_server .ssh]# ssh-keygen -l -f /etc/ssh/ssh_host_ecdsa_key.pub
256 SHA256:xRaqsG/D2EFWfKbv6Ke8ImjHXBpo3jZ3N1Xp0NVhJLg root@ssh_server (ECDSA)
[root@ssh_server .ssh]# ssh-keygen -l -f /etc/ssh/ssh_host_ecdsa_key.pub -E md5
256 MD5:d1:36:75:6d:b2:da:9d:f9:5e:ea:01:3f:6e:66:aa:e2 root@ssh_server (ECDSA)
[root@ssh_server .ssh]#
第一次连接到ssh服务端后,客户端会把服务端的公钥记录在$HOME/.ssh/known_hosts
里,这样后面再从同一个客户端(相同用户下)上连接同一ssh服务端就不会再有这个提示了,我们再从本机连接一次ssh服务端,这时没有出现服务端公钥指纹确认:
[root@ssh_client .ssh]# ssh 172.17.0.2
root@172.17.0.2's password:
Last login: Mon Mar 19 23:48:41 2018 from localhost
[root@ssh_server ~]#
我们可以看看这个known_hosts,里面记录着主机名,公钥类型,公钥 等信息.
[root@ssh_client .ssh]# pwd
/root/.ssh
[root@ssh_client .ssh]# cat known_hosts
127.0.0.1 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBH992J2KjIMS25eYhKtfYs6WM8rqMK4K29b4AoGv3xY0pNsj1LdEB4zS6dMY2U3zYrcRKsoH19shsqrUuDEmCz4=
[root@ssh_client .ssh]#
同样我们可以查查这个文件里的公钥指纹:
[root@ssh_client .ssh]# ssh-keygen -l -f ./known_hosts
256 SHA256:xRaqsG/D2EFWfKbv6Ke8ImjHXBpo3jZ3N1Xp0NVhJLg 172.17.0.2 (ECDSA)
[root@ssh_client .ssh]#
我们再试试从其他机器第一次连接这个ssh服务端(通过执行ip addr
可以查看到这个机器的ip是172.17.0.2),同样会有这个指纹确认的过程:
xxx@xxx-TP:~$ ssh root@172.17.0.2
The authenticity of host '172.17.0.2 (172.17.0.2)' can't be established.
ECDSA key fingerprint is SHA256:xRaqsG/D2EFWfKbv6Ke8ImjHXBpo3jZ3N1Xp0NVhJLg.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.17.0.2' (ECDSA) to the list of known hosts.
root@172.17.0.2's password:
X11 forwarding request failed on channel 0
Last login: Tue Mar 20 23:49:24 2018 from localhost
[root@ssh_server ~]#
我们在服务端上更新一下ecdsa的key.
[root@ssh_server .ssh]# ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key
Generating public/private ecdsa key pair.
/etc/ssh/ssh_host_ecdsa_key already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /etc/ssh/ssh_host_ecdsa_key.
Your public key has been saved in /etc/ssh/ssh_host_ecdsa_key.pub.
The key fingerprint is:
SHA256:gsnACdBRyVrZsJFSVzfJHYEhgUL9gY5bmyq08fJy6Jc root@ssh_server
The key's randomart image is:
+---[ECDSA 256]---+
|+..**B.++o+=oo |
| oo.B+= .o+.. |
| ++.+ . . |
| .o.oo . |
| +o.oS |
| o . o. |
| . = o |
| * E |
| ..B. |
+----[SHA256]-----+
[root@ssh_server .ssh]#
再次尝试登录:
[root@ssh_client .ssh]# ssh root@172.17.0.2
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ 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:gsnACdBRyVrZsJFSVzfJHYEhgUL9gY5bmyq08fJy6Jc.
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /root/.ssh/known_hosts:1
ECDSA host key for 172.17.0.2 has changed and you have requested strict checking.
Host key verification failed.
[root@ssh_client .ssh]#
这就是典型的服务端返回的host key和本地存储的不一致告警.我们这个例子中是强制更新了ssh服务端密钥对,在实际使用中,经常会出现的是:ssh服务端机器被重装了;ssh服务端的ip地址被其它机器占用了,导致连错机器等,也有可能是发生了中间人攻击,网络上有人伪装了个ssh服务端机器.
如果我们能确认host key是正常发生变动的,可以将本地存储的host key删除,重认新的host key.从前面的例子中,我们已经知道,客户端上的host key是存储在$HOME/.ssh/known_hosts里的.如果里面只有一条记录,我们可以清空这个文件,如果里面有多条记录,我们可以打开这个,定位到对应的记录,删除.
[root@ssh_client .ssh]# ls -tlr
total 4
-rw-r--r-- 1 root root 171 Mar 19 23:48 known_hosts
[root@ssh_client .ssh]# cat known_hosts
172.17.0.2 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBH992J2KjIMS25eYhKtfYs6WM8rqMK4K29b4AoGv3xY0pNsj1LdEB4zS6dMY2U3zYrcRKsoH19shsqrUuDEmCz4=
[root@ssh_client .ssh]#
我们这里只有一个文件,我们可以尝试把文件清空,为了方便后续测试,我们先把文件备份一下:
[root@ssh_client .ssh]# cp known_hosts mykh.bak
[root@ssh_client .ssh]# >known_hosts
[root@ssh_client .ssh]# cat known_hosts
[root@ssh_client .ssh]#
文件清空之后,再尝试登录:
[root@ssh_client .ssh]# ssh root@172.17.0.2
The authenticity of host '172.17.0.2 (172.17.0.2)' can't be established.
ECDSA key fingerprint is SHA256:gsnACdBRyVrZsJFSVzfJHYEhgUL9gY5bmyq08fJy6Jc.
ECDSA key fingerprint is MD5:38:6b:a9:be:47:08:08:b8:51:fe:f5:e1:c0:01:d4:ef.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.17.0.2' (ECDSA) to the list of known hosts.
root@172.17.0.2's password:
Last login: Sat Apr 7 01:11:33 2018 from localhost
[root@ssh_server ~]#
可以实现重新确认key,并正常登录.
如果known_hosts里有多于一条的记录,我们就不能简单清空文件,否则其他主机的host key信息也会被删除,需要找到我们要删除的记录,手工删除它:
[root@ssh_client .ssh]# cat known_hosts
172.17.0.2 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBH992J2KjIMS25eYhKtfYs6WM8rqMK4K29b4AoGv3xY0pNsj1LdEB4zS6dMY2U3zYrcRKsoH19shsqrUuDEmCz4=
172.17.0.1 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOD62GxuUdjHtnIgOVXQaagVlCQ21IiGtQBNVPWNszmO8oKT5EOzuZdYybTPnOS2oR/MzJ65iX4KqSeGpC7rJuQ=
[root@ssh_client .ssh]#
我们这里有两条记录,可以通过vi进去,删除172.17.0.2的那条记录,实现重认host key:
[root@ssh_client .ssh]# cp known_hosts mykh.bak
cp: overwrite 'mykh.bak'? y
[root@ssh_client .ssh]# ssh root@172.17.0.2
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ 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:gsnACdBRyVrZsJFSVzfJHYEhgUL9gY5bmyq08fJy6Jc.
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /root/.ssh/known_hosts:1
ECDSA host key for 172.17.0.2 has changed and you have requested strict checking.
Host key verification failed.
[root@ssh_client .ssh]# vi known_hosts
[root@ssh_client .ssh]# cat known_hosts
172.17.0.1 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOD62GxuUdjHtnIgOVXQaagVlCQ21IiGtQBNVPWNszmO8oKT5EOzuZdYybTPnOS2oR/MzJ65iX4KqSeGpC7rJuQ=
[root@ssh_client .ssh]# ssh root@172.17.0.2
The authenticity of host '172.17.0.2 (172.17.0.2)' can't be established.
ECDSA key fingerprint is SHA256:gsnACdBRyVrZsJFSVzfJHYEhgUL9gY5bmyq08fJy6Jc.
ECDSA key fingerprint is MD5:38:6b:a9:be:47:08:08:b8:51:fe:f5:e1:c0:01:d4:ef.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.17.0.2' (ECDSA) to the list of known hosts.
root@172.17.0.2's password:
OpenSSH有个HashKnownHosts选项,如果开启了这个选项,known_hosts里存储的就是hash后的结果:
xxx@xxx-TP:~/.ssh$ grep HashKnownHosts /etc/ssh/ssh_config
HashKnownHosts yes
xxx@xxx-TP:~/.ssh$ more known_hosts
|1|Y7vypCJauRdlINk5AYLBRjzMHZc=|+Z6FhMBXHvSNdwxWbRTnZnRhuSM= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAjejdMKtKTwP
WgoxubOie71Q8iePHJ2BDCGad37jBpU1J/0kIpnwSwK5M7TAGupXltpfvvUI7Nf1CvM/8hsFCY=
|1|HuXbxymRZ0uAXm1epm+8XY3K8/0=|p2ei6uHnnd2F8X6MQ3PAs3BYw3I= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKZLbMSYFabjt
fUcb7t/5yD43U8lPlSeuqjI96+EKDVyZxauXCuMcVWfnByQ5ssKi28BPwDRxqZPrOUAtn5d/xU=
|1|Zx92xoC3AFjKY/dUro9htuLiles=|2DbvgHAZvqr30WMNyLjw0hAb3og= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBA/xwD0eRiU/M
s5lcduwx5N5V3GvO/1NRlmxnCy0bIx2rGjFPdcvjeeowY6gBeG1WSXuIZ8vci12bpfS3Qmf+qs=
对于这种情况,靠肉眼是没法识别出哪条记录是我们需要删除的,我们需要用ssh-keygen指令来找出需要删除的host key:
xxx@xxx-TP:~/.ssh$ ssh-keygen -F 172.17.0.2
# Host 172.17.0.2 found: line 61
|1|32Y9sbXMbVva7F+CNaDLI+Nih2c=|BgmXf2XFHv3dwRhzIqFXbVT5D+w= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBH992J2KjIMS25eYhKtfYs6WM8rqMK4K29b4AoGv3xY0pNsj1LdEB4zS6dMY2U3zYrcRKsoH19shsqrUuDEmCz4=
从上面的结果可以看出,我们可以vi known_host文件,输入冒号:61
,定位到61行,按dd
删除这行.事实上ssh-keygen还有一个参数,可以直接把某个ssh服务端对应域名的host key删除,我们执行ssh指令可以看到这个提示(部分版本OpenSSH的客户端有这个提示,不管有没有这个提示,这个指令都是能执行):
xxx@xxx-TP:~/.ssh$ ssh root@172.17.0.2
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ 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:gsnACdBRyVrZsJFSVzfJHYEhgUL9gY5bmyq08fJy6Jc.
Please contact your system administrator.
Add correct host key in /home/xxx/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/xxx/.ssh/known_hosts:61
remove with:
ssh-keygen -f "/home/xxx/.ssh/known_hosts" -R 172.17.0.2
ECDSA host key for 172.17.0.2 has changed and you have requested strict checking.
Host key verification failed.
这个指令就是 ssh-keygen -f "/home/xxx/.ssh/known_hosts" -R 172.17.0.2
,
我们可以执行这个指令,再尝试登录:
xxx@xxx-TP:~/.ssh$ ssh-keygen -f "/home/xxx/.ssh/known_hosts" -R 172.17.0.2
# Host 172.17.0.2 found: line 61
/home/xxx/.ssh/known_hosts updated.
Original contents retained as /home/xxx/.ssh/known_hosts.old
xxx@xxx-TP:~/.ssh$ ssh root@172.17.0.2
The authenticity of host '172.17.0.2 (172.17.0.2)' can't be established.
ECDSA key fingerprint is SHA256:gsnACdBRyVrZsJFSVzfJHYEhgUL9gY5bmyq08fJy6Jc.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.17.0.2' (ECDSA) to the list of known hosts.
root@172.17.0.2's password:
X11 forwarding request failed on channel 0
Last login: Sat Apr 7 08:51:46 2018 from localhost
[root@ssh_server ~]#
执行ssh-keygen -f
后,可以重认host key.