什么是 SSH?
SSH(Secure Shell,安全外壳协议)是一套在不安全网络上安全访问远程计算机的协议。它在客户端和服务器之间建立经过身份确认、加密和完整性保护的连接,常用于远程登录、执行命令、推送代码和传输文件。

SSH 解决的不是“如何打开一个远程终端”这么简单,而是三个安全问题:通信内容不能被沿途读取,数据不能被悄悄修改,连接两端要能确认对方身份。默认情况下,OpenSSH 服务监听 TCP 22 端口,但端口可以由管理员改成其他值,端口号本身不是安全保证。
一句话总结:SSH 是把远程操作放进一条经过加密、认证和完整性校验的安全通道中的协议套件。
SSH 为什么要替代 Telnet?
Telnet 等早期远程登录协议通常以明文传输内容,包括用户名、密码和执行的命令。攻击者只要能在同一 Wi-Fi、交换网络或传输路径上抓包,就可能直接看到登录凭据和会话内容。

SSH 针对明文协议补上了三层保护:
- 机密性:加密后的数据不能被旁路观察者直接读懂。
- 身份认证:客户端可以验证服务器,服务器也可以验证登录用户。
- 完整性:数据被插入、删除或修改后,校验会失败,客户端不会把它当成有效消息接受。
因此,SSH 并不只是“把 Telnet 换了一个命令名”。它把远程登录从“能连上就传输”变成了“先协商安全参数、再确认身份、最后传输数据”。
SSH 连接建立时发生了什么?
一次 SSH-2 连接可以按四个关键步骤理解:协商算法、交换密钥、验证服务器、验证用户。真实报文会包含更多消息,但安全目标就是这四件事。

1. 双方如何协商加密算法?
客户端和服务器先交换各自支持的算法列表,并从交集里选出一组参数。协商内容通常包括:
- 密钥交换算法:例如基于 Diffie-Hellman 的
curve25519-sha256、diffie-hellman-group14-sha256。 - 服务器主机密钥算法:例如
ssh-ed25519、ecdsa-sha2-nistp256,用于证明服务器身份。 - 对称加密算法:例如
[email protected]、[email protected]。 - 完整性或 AEAD 算法:老式组合可能单独使用 HMAC;现代 AEAD 算法把加密和完整性校验合在一起。
- 压缩算法:双方都支持时才启用,不能把压缩误认为加密。

协商的结果会绑定到后续会话的交换哈希中,防止攻击者在中途偷偷替换算法列表。双方没有安全的共同算法时,连接会失败,而不是退回明文通信。
2. 密钥交换如何得到同一个会话密钥?
密钥交换的目标是:双方不直接发送会话密钥,却能各自计算出同一个共享秘密。SSH 常使用 Diffie-Hellman 或椭圆曲线 Diffie-Hellman(ECDH)及其临时密钥变体。

以临时 ECDH 为例:
- 客户端和服务器各自生成一次性的临时私钥,并计算对应的临时公钥。
- 双方交换临时公钥,用自己的临时私钥计算共享秘密。
- 双方根据共享秘密、双方标识和交换报文计算交换哈希。
- 从共享秘密和哈希派生出双向的加密密钥、完整性密钥和初始向量。
会话密钥不会以明文出现在网络中。后续终端输入、命令输出、文件内容等大量数据使用对称加密,因为对称算法比非对称算法更适合高吞吐传输。临时密钥在会话结束后丢弃,还能提供前向保密:即使服务器长期主机私钥日后泄露,过去录下的会话也不应因此被直接解密。
3. SSH 如何确认服务器是真的?
服务器在握手中发送主机公钥,并用对应私钥对交换上下文签名。客户端用这个公钥验证签名,再将主机公钥的指纹与本地记录比较。
第一次连接时,OpenSSH 常显示类似下面的提示:
The authenticity of host 'server.example.com' can't be established.
ED25519 key fingerprint is SHA256:...
Are you sure you want to continue connecting (yes/no/[fingerprint])?
这个提示不是让你盲目输入 yes。管理员应通过云控制台、服务器管理渠道或其他可信路径核对指纹。确认后,主机公钥会写入 ~/.ssh/known_hosts;以后同一主机的公钥发生变化,SSH 会报警,因为这可能意味着服务器重装,也可能是中间人攻击。

4. 用户身份如何验证?
服务器身份确认后,SSH 才进入用户认证阶段。最常见的是密码认证和公钥认证;企业环境还可能接入硬件密钥、证书、Kerberos 或多因素认证。

| 认证方式 | 工作方式 | 主要风险 | 常见建议 |
|---|---|---|---|
| 密码认证 | 客户端在加密通道中提交密码,服务器校验账户凭据 | 密码可能被猜测、复用或泄露 | 设置强密码,配合限速、MFA 和失败封禁 |
| 公钥认证 | 客户端用私钥签名,服务器用已登记的公钥验证 | 私钥文件或 SSH agent 被盗 | 私钥设置口令,限制权限并妥善备份 |
| SSH 证书 | 受信任 CA 为用户或主机公钥签发短期证书 | CA 私钥和签发策略需要严格保护 | 大规模组织统一管理时使用 |
密码认证发生在已加密的 SSH 通道内,网络旁路者不能直接看到密码;但服务器仍可能遭遇在线暴力尝试。公钥认证的优势是私钥不会离开本机,且随机签名比可反复猜测的密码更适合自动化登录。
SSH 公钥认证究竟是怎么工作的?
公钥认证的核心是“证明你持有私钥”,而不是把私钥上传给服务器。你先把公钥登记在服务器账户的 ~/.ssh/authorized_keys 中,连接时客户端对本次会话数据签名,服务器再用对应公钥验证签名。

一个简化流程如下:
- 客户端声明自己想使用某个公钥。
- 服务器检查该公钥是否出现在目标账户的
authorized_keys中。 - 服务器发送与本次 SSH 会话绑定的认证请求。
- 客户端用本地私钥生成签名并返回,私钥本身不出网络。
- 服务器用已登记的公钥验证签名,成功后创建用户会话。
私钥通常还应使用口令加密保存。口令保护的是磁盘上的私钥文件;SSH 连接本身的加密则保护网络中的会话数据,这是两个不同层次的防护。
SSH 的安全性由哪些机制共同提供?
SSH 的安全性不是由单个“加密开关”提供,而是由密钥交换、加密、认证和完整性校验共同组成。

| 机制 | 保护对象 | 解决的问题 | 典型实现 |
|---|---|---|---|
| 密钥交换 | 会话密钥材料 | 不直接传输密钥也能建立共享秘密 | ECDH、Curve25519、Diffie-Hellman |
| 对称加密 | 终端、命令、文件和转发数据 | 防止沿途读取 | AES-GCM、ChaCha20-Poly1305 |
| 身份认证 | 服务器和登录用户 | 防止连接到假服务器或冒用账户 | 主机公钥、用户公钥、密码、证书 |
| 完整性校验 | 每个 SSH 数据包 | 发现篡改、重放和乱序 | AEAD 标签、HMAC、序列号 |
完整性校验失败时,SSH 不会“尽量显示内容”,而是终止或拒绝该数据。需要注意,SSH 保护的是通信通道;如果用户在已经登录的服务器上执行了危险命令,协议不会替用户判断命令是否正确。
SSH 最常见的使用场景有哪些?
远程管理 Linux 服务器
最直接的用法是连接远程 Shell,在云服务器上查看日志、重启服务、修改配置或执行部署命令:

ssh user@host
ssh -p 2222 user@host
ssh -i ~/.ssh/id_ed25519 user@host
云主机经常关闭管理员账户的密码登录,仅允许密钥登录,以减少互联网扫描和密码爆破的攻击面。更完整的加固还包括禁止直接 root 登录、限制允许的用户、启用多因素认证、配置防火墙和及时更新 OpenSSH。
Git 代码推送和拉取
GitHub、GitLab 或自建 Git 服务可以把 SSH 作为远程仓库协议。执行 git push 时,Git 调用本机 SSH 客户端,复用已建立的加密和认证机制:

git remote add origin [email protected]:example/project.git
git push origin main
这里的“免密码”不是没有认证,而是由私钥签名完成认证。多人或多项目开发时,可以使用 ~/.ssh/config 为不同主机配置不同密钥,避免把同一把私钥用于所有平台。
SCP 和 SFTP 文件传输
SCP 适合简单地复制文件,SFTP 则提供目录浏览、断点续传和更完整的文件操作接口;二者都依赖 SSH 通道,通常使用 22 端口。

scp ./release.tar.gz user@host:/srv/releases/
sftp user@host
OpenSSH 的新版本中,scp 的实现默认采用 SFTP 协议传输,但命令的使用方式仍保持兼容。需要精细权限、批量操作或跨平台集成时,优先评估 SFTP 或专用对象存储工具。
如何配置 SSH 公钥登录?
在 Linux、macOS 或 WSL 中,最常见的配置过程是生成密钥、登记公钥、测试连接三步。

第一步:生成密钥对
ssh-keygen -t ed25519 -C "[email protected]"
命令会生成私钥 ~/.ssh/id_ed25519 和公钥 ~/.ssh/id_ed25519.pub。私钥只应保存在本机,并建议设置一个口令;公钥可以安全地复制到需要登录的服务器。
第二步:登记公钥
如果服务器仍允许密码登录,可以使用:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host
它会把公钥追加到服务器账户的 ~/.ssh/authorized_keys。手动配置时,应确认目录和文件权限足够严格,例如目录通常为 700、authorized_keys 通常为 600,具体还要符合服务器的安全策略。
第三步:测试并按需配置客户端
ssh -i ~/.ssh/id_ed25519 user@host
频繁连接多个主机时,可以在 ~/.ssh/config 中设置别名:
Host staging
HostName staging.example.com
User deploy
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
测试通过后,再由管理员在确认有备用登录方式的前提下关闭密码认证。不要在唯一远程会话中直接修改 SSH 配置而不准备控制台或带外恢复渠道,否则配置错误可能把自己锁在服务器外。
使用 SSH 时最容易犯哪些错误?
SSH 提供安全机制,但不替用户完成密钥管理和权限管理。以下做法会削弱它的保护:
- 无条件接受第一次指纹:没有核对指纹就输入
yes,无法排除首次连接时的中间人攻击。 - 把私钥提交到 Git 仓库或发到聊天工具:私钥一旦泄露,应立即撤销对应公钥并重新生成密钥对。
- 关闭主机密钥检查:使用
StrictHostKeyChecking=no会掩盖主机身份变化,自动化任务应采用受控的known_hosts。 - 只改端口不做加固:更换 22 端口可以减少噪声扫描,但不能替代密钥认证、限速和防火墙。
- 滥用 SSH agent 转发:
ForwardAgent yes会把本地 agent 暴露给远端主机,受控不严的跳板机可能诱导 agent 签名。 - 复用一把长期私钥:人员离职、设备丢失或项目权限变化时,难以只撤销一个范围的访问。
最小化权限同样重要。authorized_keys 支持 command=、from=、no-port-forwarding、no-agent-forwarding 等限制,可为自动化部署密钥关闭不需要的交互能力。
SSH 和 Telnet 有什么区别?
两者都可以远程登录,但安全模型完全不同。
| 对比维度 | Telnet | SSH |
|---|---|---|
| 默认端口 | 23 | 22 |
| 传输内容 | 明文 | 加密 |
| 服务器身份验证 | 协议本身不提供可靠校验 | 通过主机公钥和指纹校验 |
| 用户认证 | 常见为明文密码 | 密码、公钥、证书和多因素等 |
| 完整性保护 | 无 | MAC 或 AEAD 校验 |
| 文件传输和端口转发 | 通常需要其他工具 | 原生支持 SFTP、端口转发等通道 |
| 推荐场景 | 仅用于明确隔离的实验或遗留设备 | 生产环境远程管理、代码和文件传输 |
“端口不同”不是两者最重要的差别。真正的差别是 SSH 在协议层建立了经过身份确认的加密通道,而 Telnet 默认没有这些保护。
常见问题
SSH 是不是只用于登录 Linux?
不是。SSH 也支持 Git 远程仓库、SFTP/SCP 文件传输、端口转发、跳板机和自动化部署。只要应用需要在不可信网络上建立经过认证的加密通道,就可能使用 SSH 的连接能力。
SSH 密码登录和公钥登录哪个更安全?
配置正确时,公钥登录通常更抗在线爆破,因为攻击者不能靠猜测远程密码来通过认证。私钥必须设置口令、限制文件权限并及时轮换;如果私钥已泄露,公钥认证也会失去安全性。
SSH 指纹变了就一定是黑客攻击吗?
不一定。服务器重装、主机密钥轮换、域名指向变化都可能导致指纹变化,但中间人攻击也会产生同样现象。正确做法是通过可信渠道核对新指纹,确认原因后再更新 known_hosts,不要直接删除警告绕过检查。
SSH 加密后,服务器还能看到我执行的命令吗?
能。SSH 加密的是客户端到服务器之间的网络传输,服务器端的 SSH 服务和 Shell 仍会看到并执行命令。服务器管理员也可以通过 Shell、审计或终端录制策略记录操作。
把 SSH 服务改到其他端口就安全吗?
不安全。改端口只能减少低成本的自动化扫描噪声,不能阻止有针对性的探测。真正重要的是公钥认证、强密码策略、最小权限、防火墙、登录限速、日志审计和及时更新。
总结:SSH 是一套组合机制
SSH 不是一个只负责“打开远程终端”的单一工具,而是一套组合机制:
- 密钥交换让双方无需明文传输会话密钥,也能得到共享秘密。
- 对称加密以较低成本保护终端、命令和文件等持续数据。
- 主机和用户认证分别确认服务器是谁、登录者是谁。
- 完整性校验让篡改、伪造和乱序数据无法悄悄进入会话。

理解这条链路后,ssh user@host、git push、scp 和 sftp 就不再是彼此孤立的命令:它们都在复用同一套经过协商、加密、认证和校验的安全通道。SSH 的价值不是让远程机器消失,而是让远程操作可以在不可信网络上被安全地完成。

