你每天敲 ssh user@host,回车,几秒后就进去了。但这几秒里,客户端和服务端完成了一件很复杂的事:在完全不信任对方的前提下,建立一条安全的加密通道。
理解这个过程,是排查一切 SSH 问题的基础。
每次 SSH 连接都经历三个阶段,顺序固定:
和所有网络连接一样,先三次握手。客户端连到服务器的 22 端口(默认)。这一步和 SSH 协议无关,纯粹是 TCP 的事。
客户端 → SYN → 服务器
客户端 ← SYN+ACK ← 服务器
客户端 → ACK → 服务器
TCP 连上后,双方要做两件事:
curve25519-sha256,就用它。所以服务端会把自己的主机密钥(host key)发给客户端。客户端第一次连接时会问你:
The authenticity of host '106.54.161.116' can't be established.
ED25519 key fingerprint is SHA256:xxxxx.
Are you sure you want to continue connecting (yes/no)?
你输入 yes,这个指纹就被保存到 ~/.ssh/known_hosts。以后再连,客户端会自动比对。如果指纹变了,说明服务器被替换或有中间人攻击。
通道加密了,服务器身份确认了,最后证明"我是我"。SSH 支持多种方式:
ssh user@host 大概率走的是公钥认证。因为服务器上配了你的公钥,客户端自动用对应的私钥响应。
用 ssh -v 可以看到整个过程:
运行这个命令,观察输出:
ssh -v user@106.54.161.116 2>&1 | head -60
在输出中找这几行:
SSH-2.0-OpenSSH_8.9 — 协议版本协商Host key algorithm: ssh-ed25519 — 服务器用的主机密钥算法kex: algorithm: curve25519-sha256 — 密钥交换算法Offering public key: ~/.ssh/id_ed25519 — 客户端尝试的认证方式Authentication succeeded — 认证成功当你遇到 SSH 问题时,知道它卡在哪个阶段,就知道去哪里找原因:
| 卡在 | 可能原因 |
|---|---|
| 阶段 1 | 防火墙、端口没开、服务器没启动 sshd |
| 阶段 2 | 主机密钥变了(known_hosts 冲突)、算法不兼容 |
| 阶段 3 | 密钥没配对、权限不对、sshd 配置拒绝 |
你第一次 ssh 连接到一台新服务器,看到 fingerprint 确认提示。这发生在哪个阶段?
SSH 连接中,对称加密密钥是什么时候生成的?
下一课我们深入密钥交换——Diffie-Hellman 算法是怎么在不安全的网络上安全地协商出一个共享密钥的。