系统实践

用 SSH 管理多台服务器:配置、密钥、跳板机与移动端应急

把服务器别名、密钥认证、主机指纹、ProxyJump 和移动端应急访问整理成一套可维护的 SSH 管理工作流,并说明 Agent 转发与 root 登录风险。

· 约 8 分钟阅读 · 更新于 2026年7月17日 · 近 30 天 少于 10 次浏览

笔记本与手机经过密钥验证和中间安全关口连接多台服务器的山海风格示意图

本文整合了旧博客中关于移动设备 SSH(ID 149)、用 ~/.ssh/config 给服务器设置别名(ID 152)以及 Mac SSH 权限故障(ID 214)的记录。旧文证明手机应急和主机别名确实有用;新版把它们放进密钥、主机身份、跳板机和最小权限的完整边界中。

管理服务器越多,越不能依靠记忆 IP、复制密码和临时关闭安全检查。SSH 的配置文件不是“少打几个字符”的技巧,而是把连接身份、入口和信任规则写成可审查配置的地方。

先把连接信息写进 config

~/.ssh/config 中为每台服务器定义稳定别名:

Host blog-prod
    HostName 203.0.113.10
    User deploy
    Port 22
    IdentityFile ~/.ssh/id_ed25519_blog
    IdentitiesOnly yes

Host nas-home
    HostName 192.168.2.10
    User admin
    IdentityFile ~/.ssh/id_ed25519_nas
    IdentitiesOnly yes

之后直接使用:

ssh blog-prod

不要把真实生产 IP、用户名和内部拓扑提交到公开仓库。个人的 SSH config 也应限制权限:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/config

可以用下面的命令查看某个别名最终解析出的配置,而不发起连接:

ssh -G blog-prod

每个信任边界使用独立密钥

OpenSSH 当前默认支持 Ed25519。为生产博客创建一把独立密钥:

ssh-keygen -t ed25519 -a 64 -f ~/.ssh/id_ed25519_blog -C "blog production"

为私钥设置口令。-a 增加私钥口令派生轮数,提高私钥文件被盗后的暴力破解成本,但不能替代磁盘加密和设备锁屏。

公钥可以公开,私钥不能。把 .pub 内容添加到服务器目标用户的 ~/.ssh/authorized_keys,然后先保留现有会话,再新开一个终端验证密钥登录。只有确认新入口可用,才考虑关闭密码登录。

不建议所有服务器共享同一把长期密钥。至少按生产、家庭/NAS、测试环境分开;移动设备再使用单独密钥。某台设备丢失时,只撤销对应公钥,不必更换整个基础设施。

主机指纹验证的是“服务器是谁”

第一次连接时,SSH 会展示主机密钥指纹。它不是无意义的确认框:用户密钥证明“你是谁”,主机密钥证明“服务器是谁”。

应从云平台控制台、服务器本地终端或另一个可信渠道取得指纹,再与连接提示比较。服务器本地可以查看:

sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

不要在自动化脚本中使用:

StrictHostKeyChecking no

它会削弱对中间人攻击和错误 DNS 的发现能力。主机重装后出现指纹变化时,先确认变更来源,再删除旧记录;不要看到警告就盲目运行 ssh-keygen -R

用跳板机收窄入口

内部服务器不必全部暴露公网 SSH。可以只开放一台受控跳板机:

Host bastion
    HostName bastion.example.com
    User ops
    IdentityFile ~/.ssh/id_ed25519_bastion
    IdentitiesOnly yes

Host internal-*
    User deploy
    ProxyJump bastion
    IdentityFile ~/.ssh/id_ed25519_internal
    IdentitiesOnly yes

Host internal-app
    HostName 10.0.10.20

连接 internal-app 时,OpenSSH 先连接 bastion,再建立到目标主机的 TCP 转发。目标私钥仍由本机使用,不需要复制到跳板机。

谨慎使用 Agent 转发

ssh-agent 可以在本机保存解锁后的密钥,减少重复输入口令;但 ForwardAgent yes 会把 Agent 能力带到远端。OpenSSH 文档明确指出 Agent socket 可能被远端 root 或同一用户滥用。

默认保持:

ForwardAgent no

需要从服务器访问 Git 仓库时,优先使用该服务器专用、权限受限的 deploy key,或让 CI 把构建产物推送过去。不要为了方便把可以访问所有生产服务器的个人 Agent 转发到普通主机。

服务端最小权限

生产服务器不应把 root 密码登录作为日常入口。更稳妥的结构是:

  • 每个人或自动化任务使用独立账号和公钥。
  • 普通登录用户按需 sudo,并记录提权操作。
  • 自动部署账户只允许必要目录和服务操作。
  • 在防火墙或 VPN 层限制管理入口。
  • 修改 sshd_config 前保留现有会话,并先检查配置。

OpenSSH 服务端可使用以下方式测试配置,实际路径和服务名依发行版而异:

sudo sshd -t

测试通过后再 reload。不要在远程唯一会话中一次性关闭 root、密码和旧密钥;应逐项改变并从第二个终端验证,否则一次拼写错误就可能把自己锁在门外。

移动端只承担应急职责

旧文第一次用 iPad SSH 管理服务器时,最大的价值是“离开电脑也能处理故障”。这个需求仍然存在,但手机不应该成为完整生产控制台。

移动端建议:

  • 使用支持系统安全存储的可信 SSH 客户端。
  • 使用独立密钥,并在服务器端可单独撤销。
  • 手机启用强口令、生物识别、磁盘加密和远程擦除。
  • 通过 VPN、Tailnet 或受限跳板机访问管理网络。
  • 不在剪贴板、备忘录和聊天软件保存服务器密码或私钥。
  • 只做查看日志、重启已知服务、切换已验证版本等低歧义操作。

涉及数据库修复、防火墙重构、磁盘操作和批量删除时,应回到完整终端并保留审计记录。

一份可维护的 SSH 清单

定期确认:

  • 每个 Host 别名仍指向正确主机。
  • 离职人员、丢失设备和废弃 CI 的公钥已经移除。
  • 密钥按环境分离,不存在到处复制的万能私钥。
  • 主机指纹变化有明确变更记录。
  • 跳板机和公网入口安装安全更新并保留登录日志。
  • 至少有一条经过验证的紧急恢复渠道。

SSH 的便利不在于“随时能登进去”,而在于每次连接都能说明:从哪台可信设备、以哪个身份、经过哪个入口、到达哪台服务器,以及如何撤销这条路径。

参考:OpenSSH ssh_configOpenSSH ssh-keygenOpenSSH ssh-agentOpenSSH 项目