SSH 连接时的底层通信过程-vvv参数输出信息详解

一、基础环境与连接初始化

[root@localhost ~]# ssh -vvv 10.0.2.201
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017  # 客户端SSH/OpenSSL版本
debug1: Reading configuration data /etc/ssh/ssh_config  # 读取客户端全局配置文件
debug1: /etc/ssh/ssh_config line 58: Applying options for *  # 应用对所有主机的默认配置
debug2: resolving "10.0.2.201" port 22  # 解析目标IP+默认SSH端口22
debug2: ssh_connect_direct: needpriv 0  # 无需特殊权限即可直连
debug1: Connecting to 10.0.2.201 [10.0.2.201] port 22.  # 开始建立TCP连接
debug1: Connection established.  # TCP三次握手完成,底层连接通了
这一步是「先通网络」—— 客户端先确认自己的版本、加载配置,然后和服务器建立最基础的 TCP 连接(就像先打通电话线路)。

二、身份文件检测

debug1: permanently_set_uid: 0/0  # 以root用户(UID=0)运行
debug1: key_load_public: No such file or directory
debug1: identity file /root/.ssh/id_rsa type -1
...(重复id_dsa/ecdsa/ed25519)...

SSH 默认会优先尝试「公钥认证」,所以先去 /root/.ssh/ 目录找常用的私钥文件(id_rsa/id_dsa 等),这里显示「找不到这些文件」,属于正常现象(因为你还没生成 / 存放密钥),后续会 fallback 到密码认证。

三、协议版本协商(核心前置)

debug1: Enabling compatibility mode for protocol 2.0  # 启用SSH2.0兼容模式(现在几乎都是SSH2)
debug1: Local version string SSH-2.0-OpenSSH_7.4  # 客户端告诉服务器:我用SSH2.0,版本是OpenSSH7.4
debug1: Remote protocol version 2.0, remote software version OpenSSH_7.4  # 服务器回应:我也是SSH2.0+OpenSSH7.4
debug1: match: OpenSSH_7.4 pat OpenSSH* compat 0x04000000  # 版本匹配,兼容性没问题
双方先确认「通信语言版本」一致,避免因版本不兼容无法对话。

四、加密算法协商(核心环节)

这部分是关键,客户端给列表、服务器选最终值:

1. 客户端发送自己的算法列表(KEXINIT)

debug1: SSH2_MSG_KEXINIT sent  # 客户端把自己支持的算法列表发给服务器
debug2: local client KEXINIT proposal  # 客户端的算法提案(重点看下面的ciphers)
# 密钥交换(KEX)算法列表(用于协商会话密钥)
debug2: KEX algorithms: curve25519-sha256,curve25519-sha256@libssh.org,...
# 主机密钥算法(用于验证服务器身份)
debug2: host key algorithms: ecdsa-sha2-nistp256-cert-v01@openssh.com,...
# 核心:客户端支持的加密算法(ctos=服务器→客户端,stoc=客户端→服务器)
debug2: ciphers ctos: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,...
debug2: ciphers stoc: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,...
# MAC算法(消息认证码,用于校验数据完整性)
debug2: MACs ctos: umac-64-etm@openssh.com,umac-128-etm@openssh.com,...
# 压缩算法
debug2: compression ctos: none,zlib@openssh.com,zlib

客户端把 chacha20-poly1305@openssh.com 放在加密算法列表的第一位(优先级最高)。

2. 服务器返回自己的算法列表

debug1: SSH2_MSG_KEXINIT received  # 客户端收到服务器的算法列表
debug2: peer server KEXINIT proposal  # 服务器的算法提案
# 服务器支持的加密算法(比客户端多了blowfish-cbc/3des-cbc等)
debug2: ciphers ctos: chacha20-poly1305@openssh.com,aes128-ctr,...,blowfish-cbc,3des-cbc
debug2: ciphers stoc: chacha20-poly1305@openssh.com,aes128-ctr,...,blowfish-cbc,3des-cbc

3. 服务器最终选定算法(拍板)

debug1: kex: algorithm: curve25519-sha256  # 最终选的密钥交换算法
debug1: kex: host key algorithm: ecdsa-sha2-nistp256  # 最终选的主机密钥算法
# 核心结论:服务器选定 chacha20-poly1305@openssh.com 作为加密算法!
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

服务器从客户端的列表里,选了客户端优先级最高的 chacha20-poly1305@openssh.com(因为服务器也支持这个算法),MAC 显示<implicit>是因为 chacha20-poly1305 本身集成了 MAC(Poly1305),不需要额外指定。

五、服务器身份验证(确认不是钓鱼服务器)

debug1: Server host key: ecdsa-sha2-nistp256 SHA256:eg6ad6FQeVkYH9FRuSXaQPgnw3gsKBERhHIWaxsWpwc
debug3: load_hostkeys: loaded 1 keys from 10.0.2.201
debug1: Host '10.0.2.201' is known and matches the ECDSA host key.

客户端检查服务器的公钥是否在 /root/.ssh/known_hosts 里(之前连过,已经记录),确认是目标服务器而非仿冒的。

六、会话密钥生成(加密通信准备)

debug1: SSH2_MSG_NEWKEYS sent  # 客户端生成会话密钥并告知服务器
debug1: SSH2_MSG_NEWKEYS received  # 服务器确认会话密钥
debug1: rekey after 134217728 blocks  # 约定传输多少数据后重新协商密钥(安全机制)

双方用协商好的密钥交换算法,生成一个「临时会话密钥」,后续所有通信都用这个密钥 + 选定的 chacha20 算法加密。

七、身份认证环节(登录验证)

debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password  # 服务器支持的认证方式
# 1. 尝试GSSAPI认证(Kerberos):失败(无凭证)
debug1: Next authentication method: gssapi-keyex
debug1: No valid Key exchange context
# 2. 尝试公钥认证:失败(找不到私钥文件)
debug1: Next authentication method: publickey
debug1: Trying private key: /root/.ssh/id_rsa
debug3: no such identity: /root/.ssh/id_rsa: No such file or directory
# 3. 最后尝试密码认证:提示输入密码
debug1: Next authentication method: password
root@10.0.2.201's password:

SSH 按优先级依次尝试认证方式,最终落到密码认证,等待你输入密码完成登录。

总结(核心关键点)

  1. 加密算法协商逻辑:客户端把 chacha20-poly1305 放在算法列表首位,服务器因支持该算法,最终选定它作为通信加密算法。
  2. 连接核心流程:TCP 连接 → 版本协商 → 算法协商 → 服务器身份验证 → 会话密钥生成 → 登录认证。
  3. 日志关键信息kex: server->client cipher: chacha20-poly1305@openssh.com 是最终加密算法的结论,也是你最需要关注的行。

整个过程,客户端提偏好列表,服务器做最终决定,这里服务器选择了客户端最优先的 chacha20-poly1305。