案发现场
一个xilinx芯片的板卡,跑的ubuntu系统,SD卡启动,在原本的板卡上启动运行一切正常。换了一个新的板卡之后网络通信都正常,但是唯独ssh连接失败。新的板卡换了emmc, 网卡phy芯片型号。
问题原因猜测
完全一样的镜像原硬件上可以跑,新板子不行,那一定是硬件的什么改动导致的这个问题出现,而不是一个软件问题。
做过的排查尝试
1. ping测试
先用ping 命令测试网路联通性,互相ping都正常,且可以访问互联网。
2. telnet测试
给这个系统里又安装了telnet相关组件(上网apt-get这不是都正常的嘛),果然telnet这种不需要加密的通信连接是正常的。
3. ssh连接分析
详细分析ssh连接到底是哪个环节出了问题,使用命令ssh -vvv root@192.168.0.102
打印连接时的log如下:
debug1: kex: algorithm: curve25519-sha256
debug1: kex: host key algorithm: ssh-ed25519
debug1: kex: server->client cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none
debug1: kex: client->server cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none
debug3: send packet: type 30
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug3: recv - from CB ERROR:10060, io:000001F75500E8B0
下面先来了解下ssh协议的过程再来分析上述日志。
SSH(Secure Shell)协议提供了一种安全的远程连接方式,主要用于在不安全的网络中安全地进行数据通信。以下是 SSH 连接过程的详细步骤:
1. 客户端发起连接
建立 TCP 连接:客户端使用 TCP 与 SSH 服务器建立连接,默认端口为 22。
2. 服务器响应
SSH 版本交换:服务器在连接建立后,首先向客户端发送其 SSH 版本信息,格式如下:SSH-2.0-OpenSSH_X.Y
客户端也发送版本信息:客户端接收到服务器的版本信息后,返回自己的版本信息。
3. 密钥交换
密钥交换算法协商:客户端和服务器协商使用的密钥交换算法(如 Diffie-Hellman)。
生成共享密钥:通过密钥交换算法生成一个共享密钥,后续的通信将使用此密钥进行加密。
4. 服务验证
服务器公钥认证:服务器将其公钥发送给客户端,客户端会检查此公钥是否与之前保存的公钥匹配。
第一连接时的信任:如果是第一次连接,客户端会提示用户接受服务器公钥(此时需要用户确认)。
5. 客户端身份验证
身份验证方式:客户端可以选择多种身份验证方式,例如:
密码认证:客户端输入用户名和密码。
公钥认证:客户端使用私钥进行身份验证,服务器检查对应的公钥。
认证成功后:如果身份验证成功,连接将继续。
6. 会话建立
建立加密通道:使用之前生成的共享密钥,客户端和服务器之间建立一个加密的通信通道。
会话开始:此时,客户端可以发送命令,服务器可以返回执行结果,所有数据都经过加密处理。
7. 连接维护
保持活跃:SSH 连接可以通过心跳机制保持活跃,防止超时断开。
会话结束:当用户退出或连接被中断,SSH 会话结束。
8. 连接断开
关闭连接:客户端或服务器都可以主动关闭连接,释放资源。
根据最后记录可知等待SSH2_MSG_KEX_ECDH_REPLY超时,这个是双方做密钥交换环节,在等服务端返回一个密钥时等超时了。另外测试问题设备连接其他服务器时会出现发送密匙的时候就会超时。可以推测密匙交换环节的大数据包不能正常发送。
3. 修改MTU
根据查到的资料,改小MTU可能会解决问题,尝试后无效。
破案
最后硬件同事想起来没有给phy芯片焊接上拉电阻,于是焊上解决问题。
 ̄□ ̄||,白忙活半天。
这个问题根本原因在于密匙交换过程发的数据很大,但没有上拉电阻通信质量不行,而之前的ping等网络测试数据包都不大,所以没有触发这个问题。