一个完整的ssh链接建立过程,包括以下步骤:
- tcp建链(建立tcp连接);
- ssh版本协商;
- ssh算法协商(密钥交换算法,加密算法等);
- 认证阶段,服务端和客户段身份认证;
- 建立会话(会话请求阶段);
- 交互阶段(会话建立以后,ssh链接就建立完了,后面可以依托会话进行信息交互);
tcp建链阶段:通过tcp三次握手,建立tcp连接(ssh协议依托tcp服务);
ssh版本协商阶段:
下面结合一个具体问题分析:
问题现象:ssh连接失败,在/var/log/messages中报如下图所示错误
问题环境:openEuler-20.03-lts-sp1
原因分析:服务端与客户端支持的秘钥交换算法不一致导致,服务端未支持diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1秘钥交换算法。
解决办法:确保服务端与客户端支持的秘钥交换算法一致。
可以在问题环境的文件/etc/ssh/sshd_config末尾增加以下内容,指定开启三种ssh秘钥交换算法的支持
KexAlgorithms diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1
然后重启服务systemctl restart sshd
参考示例:
问题场景:两台openeuler-20.03-lts-sp1虚拟机环境之间ssh,其中server端支持的秘钥交换算法定义在/etc/ssh/sshd_config文件中,如下图,表示server端仅支持diffie-hellman-group14-sha256一种算法
client端支持的秘钥交换算法定义在/etc/ssh/ssh_config中,如下图,表示client端仅支持如图所示3种秘钥交换算法
此时,client端和server端支持的秘钥交换算法是不一样的
在client端执行ssh会失败,查看/var/log/messages会看到如下图所示报错
解决方案:修改/etc/ssh/sshd_config使server端与client端支持的秘钥交换算法一致,即在sshd_config最后一行添加client端的3种秘钥交换算法
保存,然后执行systemctl restart sshd重启服务
结果:执行ssh成功
备注:
1.在sshd_config或者ssh_config种未定义KexAlgorithms的时候,系统默认支持的秘钥交换算法定义在/etc/crypto-policies/back-ends/opensshserver.config和/etc/crypto-policies/back-ends/openssh.config中,但是这些秘钥交换算法不一定全部都使能了(参考本文档末尾的链接资料)。
2.由于本地两台20.03-lts-sp1的虚拟机未复现出客户环境的问题,因此通过“参考示例”中的方式构造出了客户环境出现的问题,并说明了如何解决。
参考资料
- http://www.openssh.com/legacy.html