加密与安全通信

SSH (安全外壳协议)

约 5 分钟阅读

什么是 SSH

SSH(Secure Shell)是一种加密网络协议,用于在不安全的网络上安全地访问远程计算机。它对所有通信进行加密,确保密码、命令和数据不会被第三方截获。

在 SSH 出现之前,Telnet 和 rlogin 等协议以明文传输数据,容易被窃听。1995 年,芬兰研究员 Tatu Ylönen 开发了 SSH,后来通过 OpenSSH 项目成为事实上的标准。

如今,SSH 被广泛用于服务器管理、云基础设施操作、Git 仓库访问、自动化部署流水线等场景。默认端口号为 22。

公钥认证的工作原理

SSH 最推荐的认证方式是公钥认证,它使用一对数学关联的密钥(公钥和私钥)代替密码进行身份验证。

  1. 生成密钥对:在客户端运行 ssh-keygen 命令,生成公钥和私钥。私钥保存在客户端,绝不能泄露。
  2. 注册公钥:将公钥添加到服务器的 ~/.ssh/authorized_keys 文件中。
  3. 认证过程:服务器发送随机挑战数据,客户端用私钥签名,服务器用公钥验证签名。私钥本身不会在网络上传输。
密码认证
设置简单,但容易受到暴力破解攻击。密码在网络上传输(虽然加密,但在服务器端会被解密)。
公钥认证
私钥不离开客户端,即使被截获也无法利用。暴力破解实际上不可能。设置密码短语可以在私钥文件泄露时提供额外保护。

目前推荐使用 Ed25519 算法。RSA 仍然广泛使用,但建议密钥长度至少 4096 位。DSA 和 ECDSA(nistp256)因安全问题已不推荐使用。

端口转发

SSH 端口转发(隧道)通过加密的 SSH 连接安全地路由其他协议的流量。

  • 本地转发:将本地端口的连接通过 SSH 隧道转发到远程目标。例如:ssh -L 3306:db-server:3306 bastion 通过跳板机连接数据库。适用于访问防火墙后面的服务。
  • 远程转发:将远程端口的连接通过隧道转发回客户端。用于将 NAT 后面的服务暴露到外部。
  • 动态转发:将 SSH 连接用作 SOCKS 代理。ssh -D 1080 server 配合浏览器代理设置,可以将所有网页流量通过 SSH 隧道传输,在公共 Wi-Fi 上提供保护。

当需要安全访问特定服务但不需要建立完整 VPN 时,端口转发非常实用。通过跳板机的多跳 SSH 连接可以使用 ~/.ssh/config 中的 ProxyJump 指令简洁配置。

SCP 和 SFTP 文件传输

SCP(安全复制协议)
一条命令即可复制文件:scp file.txt user@server:/path/。不支持断点续传。从 OpenSSH 9.0 开始,SCP 内部使用 SFTP 协议。
SFTP(SSH 文件传输协议)
支持交互式文件操作,包括目录列表、删除、重命名和断点续传。有丰富的 GUI 客户端(WinSCP、FileZilla、Cyberduck)。注意不要与 FTPS(FTP over TLS)混淆。

传统 FTP 以明文传输密码和文件内容。除非需要兼容旧系统,新项目应一律选择 SFTP。

SSH 安全最佳实践

  • 禁用密码认证:在 /etc/ssh/sshd_config 中设置 PasswordAuthentication no,仅允许公钥认证。仅此一项就能消除大部分暴力破解攻击。
  • 禁止 root 登录:设置 PermitRootLogin no,以普通用户登录后使用 sudo 提权。
  • 更改默认端口:从 22 端口改为其他端口。虽然不能从根本上提高安全性,但能大幅减少自动扫描攻击。
  • 限制来源 IP:使用防火墙或云安全组将 SSH 访问限制在已知 IP 地址。
  • 部署 Fail2ban:自动封锁多次认证失败的 IP 地址,有效防御暴力破解。
  • 定期轮换密钥:定期更新 SSH 密钥,及时从 authorized_keys 中删除离职人员的密钥。

常见误解

SSH 只有系统管理员才会用
开发人员通过 SSH 访问 Git 仓库(git@github.com:...),CI/CD 流水线通过 SSH 部署代码,数据科学家通过 SSH 连接远程 GPU 服务器。几乎所有 IT 从业者都在日常工作中使用 SSH。
改了 SSH 端口就安全了
更改端口可以减少自动扫描,但通过端口扫描很容易发现。真正的安全需要禁用密码认证、强制公钥认证、限制来源 IP 等多重措施。
SSH 密钥创建后可以永久使用
SSH 密钥应该定期轮换。风险包括离职人员密钥未删除、私钥泄露可能性以及加密算法过时等问题。
分享

相关术语