← 返回文章

一文搞懂 SSH 协议:从原理到日常使用

每天都在敲 `ssh user@host`,`git clone git@github.com:...`,但你真的知道这条命令背后发生了什么吗?这篇文章把 SSH 的原理、认证方式、常见用法和安全实践一次讲清楚。

·6 分钟阅读

一文搞懂 SSH 协议:从原理到日常使用

每天都在敲 ssh user@host,git clone git@github.com:...,但你真的知道这条命令背后发生了什么吗?这篇文章把 SSH 的原理、认证方式、常见用法和安全实践一次讲清楚。

一、SSH 是什么

SSH(Secure Shell) 是一种在不安全网络上建立加密通道的网络协议,主要用于安全地远程登录和管理服务器。它基于 TCP,默认端口是 ​22​。

SSH 诞生的背景很直接:早期的 Telnet、rlogin、FTP 都是​明文传输​,用户名、密码和命令内容在网络上一览无余,任何能抓包的人都能窃听。1995 年 SSH 出现,就是为了取代它们。

二、SSH 解决了哪些问题

威胁 SSH 的应对
窃听 数据全程加密(confidentiality)
篡改 使用 MAC 校验数据完整性(integrity)
冒充服务器 通过 host key 验证服务器身份
冒充用户 密码或公钥等方式认证用户

三、协议结构:三层模型

目前通用的 SSH-2 由三层组成:

  1. **Transport Layer(传输层)**负责版本协商、算法协商、密钥交换(如 Diffie-Hellman、ECDH)和服务器认证,建立起加密通道。
  2. **User Authentication Layer(用户认证层)**在已加密的通道内验证用户身份。
  3. **Connection Layer(连接层)**把一条 SSH 连接复用成多个逻辑 channel,分别承载 shell、命令执行、端口转发、SFTP 等。

这个分层设计的好处是:加密、认证、业务通道互相解耦,所以同一条连接上可以同时跑交互式终端和文件传输。

四、一次连接是怎么建立的

1. 客户端连接服务器的 22 端口,双方交换协议版本号
2. 协商加密算法、MAC 算法、压缩算法
3. 密钥交换,双方各自算出相同的会话密钥(session key)
4. 客户端校验服务器的 host key
5. 用户认证(密码 / 公钥等)
6. 打开 channel,开始交互

第 4 步:你一定见过的那个提示

第一次连接新服务器时,会看到:

The authenticity of host 'example.com (1.2.3.4)' can't be established.
ED25519 key fingerprint is SHA256:xxxx...
Are you sure you want to continue connecting (yes/no)?

这就是在让你确认服务器的 host key 指纹。输入 yes 后,指纹会保存到本地的 ~/.ssh/known_hosts。

之后如果同一个地址的指纹变了,SSH 会弹出醒目的警告(WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!)。这是防御**中间人攻击(MITM)**的关键机制。遇到这个警告,别急着删 known_hosts 里的记录,先确认服务器是否真的重装或换了密钥。

第 3 步:会话密钥是怎么来的

密钥交换的精髓在于:双方​不需要在网络上直接传输密钥​,而是通过 Diffie-Hellman 一类的算法,各自用对方公开的信息算出同一个共享秘密,再派生出会话密钥。即使有人全程抓包,也无法还原出这个密钥。

之后的数据都用会话密钥做对称加密,因为对称加密比非对称加密快得多。

五、两种主要的认证方式

1. 密码认证

输入用户密码即可,上手简单,但容易被暴力破解,公网服务器上尤其危险。

2. 公钥认证(推荐)

流程:

  • 在本地生成一对密钥:​私钥​(如 ~/.ssh/id_ed25519,绝不外传)和​公钥​(id_ed25519.pub)。
  • 把公钥放到服务器的 ~/.ssh/authorized_keys。
  • 登录时,服务器发出挑战,客户端用私钥签名,服务器用公钥验证签名。私钥本身从不在网络上传输。

实际操作:

# 1. 生成密钥(推荐 Ed25519)
ssh-keygen -t ed25519 -C "your_email@example.com"

# 2. 把公钥上传到服务器
ssh-copy-id user@host

# 3. 登录
ssh user@host

生成密钥时建议设置 passphrase,这样即使私钥文件泄露,别人也无法直接使用。

六、SSH 的常见用途

远程登录与执行命令

ssh user@host                       # 交互式登录
ssh user@host "df -h"               # 执行单条命令后退出
ssh -p 2222 user@host               # 指定端口
ssh -i ~/.ssh/my_key user@host      # 指定私钥

文件传输

scp local.txt user@host:/tmp/            # 复制文件
scp -r ./dir user@host:/tmp/             # 复制目录
sftp user@host                           # 交互式文件传输
rsync -avz -e ssh ./dir user@host:/tmp/  # 增量同步

端口转发(隧道)

这是 SSH 最强大也最容易被忽视的功能。

​**本地转发(-L)**​:把本地端口映射到远端能访问到的地址。

# 访问本机 8080,等于访问服务器所在网络里的 db.internal:3306
ssh -L 8080:db.internal:3306 user@host

​**远程转发(-R)**​:把服务器上的端口映射回本地。

# 服务器的 9000 端口转发到本机的 3000 端口
ssh -R 9000:localhost:3000 user@host

​**动态转发(-D)**​:开一个 SOCKS 代理。

ssh -D 1080 user@host

Git over SSH

git clone git@github.com:owner/repo.git

这用的就是 SSH 公钥认证。把公钥添加到 GitHub 账户之后,推拉代码就不需要再输入密码。测试连通性:

ssh -T git@github.com

七、用 ~/.ssh/config 让生活更轻松

每次都敲一长串参数很烦,可以写进配置文件:

Host myserver
    HostName 1.2.3.4
    User deploy
    Port 2222
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 60

Host github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_github

之后只需要:

ssh myserver

ServerAliveInterval 会定期发心跳,防止连接因为空闲被路由器或防火墙断开。

八、SSH 版本与常见实现

  • ​SSH-1​:1995 年出现,有设计缺陷,已经淘汰。
  • ​SSH-2​:2006 年标准化(RFC 4251–4254 等),与 SSH-1 不兼容,是现在的通用版本。

常见实现:

  • ​OpenSSH​:最主流,Linux、macOS、Windows 10+ 都自带。
  • ​PuTTY​:Windows 上常用的客户端。
  • ​Dropbear​:轻量级实现,常见于路由器和嵌入式设备。

九、安全加固建议

编辑服务器的 /etc/ssh/sshd_config:

PasswordAuthentication no     # 关闭密码登录,只允许公钥
PermitRootLogin no            # 禁止 root 直接登录
PubkeyAuthentication yes

修改后重载服务(注意先保留一个已登录的会话,确认新配置可用再退出,避免把自己锁在门外):

sudo systemctl reload sshd    # 部分发行版服务名为 ssh

其他实践:

  • 私钥权限设为 600(chmod 600 ~/.ssh/id_ed25519),~/.ssh 目录设为 700。
  • 优先使用 Ed25519 这类现代密钥类型。
  • 私钥加 passphrase,配合 ssh-agent 避免反复输入。
  • 配合 fail2ban 之类的工具封禁暴力破解的 IP。
  • 改默认端口只能减少日志噪音,不能算真正的安全措施。

十、常见问题排查

1. Permission denied (publickey)

  • 公钥是否已写入服务器的 authorized_keys?
  • 服务器上 ~/.ssh 为 700、authorized_keys 为 600?权限过宽 sshd 会拒绝使用。
  • 用 ssh -v user@host 查看详细握手日志,必要时加 -vvv。

2. Connection refused / Connection timed out

  • 服务器是否运行了 sshd?
  • 防火墙或云厂商安全组是否放行了对应端口?
  • 端口是否被改动过?

3. REMOTE HOST IDENTIFICATION HAS CHANGED

  • 先确认服务器是否重装过。确认安全后,再用 ssh-keygen -R host 清除旧记录。

4. 连接一会儿就断

  • 在配置里加 ServerAliveInterval 60。

总结

SSH 的本质,是通过​密钥交换 + 对称加密 + 完整性校验 + 身份认证​,让你能够安全地远程操控另一台机器、传输数据、甚至搭建隧道。

记住几个关键点:

  1. 三层结构:传输层、认证层、连接层。
  2. host key 校验防的是服务器被冒充,公钥认证防的是用户被冒充。
  3. 能用公钥就不用密码,并且给私钥加 passphrase。
  4. 善用 ~/.ssh/config 和端口转发,效率会提升一大截。

参考

  • RFC 4251:The Secure Shell (SSH) Protocol Architecture
  • RFC 4252:The Secure Shell (SSH) Authentication Protocol
  • RFC 4253:The Secure Shell (SSH) Transport Layer Protocol
  • RFC 4254:The Secure Shell (SSH) Connection Protocol
  • OpenSSH 官方文档:https://www.openssh.com
© 2026 Carreyda