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

本文整合了旧博客中关于移动设备 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_config、OpenSSH ssh-keygen、OpenSSH ssh-agent与 OpenSSH 项目。

