本页目录

SSH 协议

SSH 不只是"加密的 telnet"——传输层(密钥交换+加密)、认证层(公钥/密码/证书)、连接层(端口转发/X11/SFTP 多路复用)三层分离。端口转发让 SSH 变成了"瑞士军刀"。

概述

SSH(Secure Shell, 1995/2006)是 Unix/Linux 系统管理的核心工具。协议分为三层:Transport Layer 做密钥交换和加密、User Authentication Layer 做身份验证(公钥/密码/TOTP)、Connection Layer 在单一 TCP 连接上多路复用 shell/port forwarding/SFTP 等 channel。SSH 的端口转发(-L/-R)可以作为简易 VPN——通过加密隧道将远程端口映射到本地。SSH 2.0 修复了 SSH 1.x 的严重安全问题,是现代唯一安全的版本。

三层架构

Connection Protocol (RFC 4254):  channels (shell, exec, forward, SFTP)
User Authentication (RFC 4252):  password, publickey, keyboard-interactive
Transport Layer (RFC 4253):      key exchange, encryption, server auth
TCP

Transport Layer: 密钥交换 (curve25519-sha256)

SSH 密钥交换五步走(curve25519-sha256) ① 建立连接与协商算法 ② DH 密钥交换 ③ 派生密钥与验证主机 版本交换 C ↔ S 互换 SSH-2.0-OpenSSH_9.6 算法协商(KEXINIT) 候选表:kex / host_key 加密算法 / MAC 算法 C → S: KEX_ECDH_INIT 发送临时公钥 Q_C S → C: KEX_ECDH_REPLY K_S(主机公钥)+ Q_S(临时公钥) signature over H,证明持有私钥 计算共享密钥 shared secret → H = session_id 派生 IV / 加密key / MAC key(双向) 客户端验证 K_S 首次连接:核对指纹 写入/比对 known_hosts 验证顺序是关键:签名先证明服务器持有 K_S 私钥,known_hosts 比对再防中间人劫持。 首次连接的信任依赖 TOFU(Trust On First Use)——这是 SSH 唯一无法自动化验证的环节。

User Authentication

方法 (按顺序尝试):
  1. publickey: 客户端: sign(session_id + request + publickey, privatekey)
     服务器: verify → SSH_MSG_USERAUTH_SUCCESS
  2. keyboard-interactive: TOTP 或 challenge-response
  3. password: 在加密通道中传输 (安全)

Connection Layer: Channel 多路复用

每 channel 独立:
  SSH_MSG_CHANNEL_OPEN: type="session" → channel 0
  SSH_MSG_CHANNEL_OPEN: type="direct-tcpip" → channel 1 (port forwarding)

Channel types:
  session:         shell, exec, subsystem (SFTP)
  direct-tcpip:    本地端口转发 (-L)
  forwarded-tcpip: 远程端口转发 (-R)

Port Forwarding

Local (-L 8080:internal:80): SSH 客户端监听:8080 → tunnel → SSH服务端连 internal:80
Remote (-R 3000:localhost:22): SSH 服务端监听:3000 → tunnel → SSH客户端连 localhost:22

参考

  • RFC: 4251-4254, 5656, 8731
  • 源码⁠: OpenSSH (sshconnect2.c for auth, channels.c for channels)

Keywords: SSH, transport, kex, publickey, channel, port forwarding, SFTP, known_hosts