“did not receive identification string”错误源于tcp握手后ssh协议层交互失败,需用tcpdump分层验证:先确认syn/syn-ack/ack是否完整,再检查服务端是否发出“ssh-2.0-”字符串,结合ss和日志定位防火墙、sshd异常或客户端算法不兼容等问题。

SSH 握手失败(比如报错 “Did not receive identification string” 或连接直接被关闭)通常不是密码或密钥问题,而是卡在 TCP 建立后、SSH 协议层刚开始交互的阶段。tcpdump 能帮你确认:是连不上服务器,还是连上了却没发/收到 SSH 版本字符串?关键在于分层验证。
确认网卡和权限,先让 tcpdump 正常运行
普通用户无法抓包,必须用 root 或 sudo:
- 查可用网卡:sudo tcpdump -D(常见如 ens33、eth0、enp0s3;云服务器可能是 eth0 或 ens5)
- 基础命令必须带三个参数:-i 指定网卡 -nn 禁DNS和端口名 -s0 抓完整包,否则可能看不到 SSH 字符串或解析出错
- 别用 any 接口抓 SSH,容易混入 loopback 流量干扰判断
精准过滤 SSH 流量,聚焦三次握手和初始协议交互
只抓目标 IP 和 22 端口,并突出 SYN/SYN-ACK/ACK 和后续应用层内容:
- 推荐命令:sudo tcpdump -i ens33 -nn -s0 -A 'host 192.168.1.100 and port 22'(把 192.168.1.100 换成你的客户端真实 IP)
- 想更聚焦握手阶段,可加标志位过滤:tcp[tcpflags] & (tcp-syn|tcp-ack) != 0
- 如果服务端日志显示 “Did not receive identification string”,重点看抓包里有没有从服务端发出的 SSH-2.0-OpenSSH_* 这类明文字符串(-A 参数确保能看见 ASCII 内容)
对照三次握手和 SSH 字符串,快速定位断点
按顺序检查抓包输出中的关键信号:
- 只有客户端 SYN,无任何响应 → 服务端根本没收到包:查安全组/防火墙是否放行 22 端口、ss -tlnp | grep :22 确认 sshd 是否在监听、路由是否可达
- 有 SYN 和 SYN-ACK,但没有后续 ACK → 客户端未响应:可能是客户端本地防火墙拦截、网络丢包、或中间设备(如 NAT 网关)异常截断
- 三次握手完整,但服务端没发 SSH 字符串(即没看到 SSH-2.0- 开头的行)→ 服务端 sshd 进程异常:检查 sshd 是否崩溃、MaxStartups 是否耗尽、或配置了 PermitRootLogin no 且客户端用 root 连接被静默拒绝
- 看到服务端发了 SSH 字符串,但客户端没回 → 客户端侧问题:如 OpenSSH 版本太老、启用了已被禁用的算法(如 diffie-hellman-group1-sha1),此时需配合 Wireshark 看 KEXINIT 报文协商细节
配合 ss 和日志,交叉验证结论
tcpdump 只告诉你“网络上发生了什么”,还需系统层面佐证:
- 查 sshd 是否真在监听:sudo ss -tlnp | grep :22(注意 LISTEN 状态,不是 ESTABLISHED)
- 看实时连接状态:sudo ss -tn state syn-sent(客户端视角)、sudo ss -tn state syn-recv(服务端视角)
- 查服务端日志:sudo journalctl -u sshd -n 50 -f 或 /var/log/auth.log,关注 connection closed、no matching key exchange method 等提示











