安全高效的SSH最佳实践
随着管理的主机和云端资产不断增加,传统的单文件 ~/.ssh/config 配置方式会变得愈发臃肿且难以维护。一旦配置管理不当,还可能埋下安全隐患。
本文分享一套兼顾安全性与运维效率的 SSH 客户端配置方案。其核心逻辑在于:利用 FIDO2 硬件密钥保障核心资产安全,通过 conf.d 目录实现配置的模块化解耦,并借助 ControlMaster 实现连接复用以提升日常操作效率。
1 1. 本地目录初始化与权限控制
SSH 服务对本地文件和目录的权限配置极其严格,任何权限过大的配置都可能导致认证失败。在配置开始前,需先初始化配置解耦所需的子目录以及连接复用目录,并严格限制其访问权限:
# 创建配置拆分目录、密钥存储目录以及连接复用目录
mkdir -p ~/.ssh/conf.d ~/.ssh/keys ~/.ssh/controlmasters
touch ~/.ssh/config
# 严格限制权限:目录设为 700,配置文件设为 600
chmod 700 ~/.ssh/conf.d ~/.ssh/keys ~/.ssh/controlmasters
chmod 600 ~/.ssh/config2 2. 密钥生成策略:硬件密钥 vs 传统密钥
根据目标服务器的安全级别与使用场景,建议采取差异化的密钥生成策略。
2.1 硬件密钥 (FIDO2 / U2F)
针对生产环境(Prod)与核心堡垒机(Bastion),强制启用支持 FIDO2 的硬件密钥。在此机制下,即使本地私钥文件不幸泄露,攻击者在没有物理硬件媒介触碰的情况下也绝对无法通过身份验证。
cd ~/.ssh/keys
# 生成基于 FIDO2 的 Ed25519 密钥对
# -O resident: 将凭据留存在硬件内,便于在新设备上进行物理恢复
# -O verify-required: 强制开启 PIN 码二次验证
ssh-keygen -t ed25519-sk \
-O resident \
-O verify-required \
-O application="ssh:Cloudhost-Sens-2026" \
-C "Cloudhost-Sens-2026" \
-f id_ed25519_sk_sens2.2 标准密钥 (Ed25519)
针对开发环境(Dev)或不支持硬件密钥的边缘场景,推荐使用性能与安全性更佳的标准 Ed25519 算法,以替代过时的 RSA。
# 生成标准 Ed25519 密钥
ssh-keygen -t ed25519 \
-O application="ssh:Standard-2026" \
-C "Standard-2026" \
-f id_ed25519_std
# 为标准私钥设置强 Passphrase 密码以增强物理安全性
ssh-keygen -p -f ~/.ssh/keys/id_ed25519_std3 3. SSH 客户端配置模块化拆分
为了规避单配置文件带来的维护灾难,我们利用 Include 机制,按照数字前缀的优先级顺序加载子配置文件。
3.1 主入口配置:~/.ssh/config
主配置文件仅负责全局兼容性设定与子配置目录的分流。
# 忽略 macOS 专属配置项导致的未知错误(如 UserKeychain),确保跨平台兼容
IgnoreUnknown UserKeychain
# 引入子配置文件
Include ~/.ssh/conf.d/*.conf3.2 核心敏感区配置:~/.ssh/conf.d/10-sensitive.conf
面向核心资产(Bastion/Prod 等),采取高强度的防御性配置,严格收敛权限。
# 10-sensitive.conf
Host bastion prod core-* sensitive
# 强制仅使用指定的密钥,拒绝 Agent 自动尝试其他密钥(防止因密钥穷举触发拒绝服务)
IdentitiesOnly yes
IdentityFile ~/.ssh/keys/id_ed25519_sk_sens1
IdentityFile ~/.ssh/keys/id_ed25519_sk_sens2
# 禁用 SSH Agent 转发,切断由于跳板机沦陷导致的凭据劫持通路
IdentityAgent none
AddKeysToAgent no
ForwardAgent no
StrictHostKeyChecking yes
PasswordAuthentication no
LogLevel VERBOSE3.3 日常访问与隧道配置:~/.ssh/conf.d/20-access.conf
配置具体主机的路由别名、动态端口转发(Socks5 隧道)以及特定的环境配置。
# 20-access.conf
Host core-kali
HostName 52.52.50.188
User kali
Port 22
PubkeyAuthentication yes
IdentitiesOnly yes
IdentityFile ~/.ssh/keys/id_ed25519_sk_sens1
Host test-vm-kali
HostName 192.168.56.129
User kali
Port 22
IdentitiesOnly yes
IdentityFile ~/.ssh/keys/id_ed25519_std
IdentityFile ~/.ssh/keys/id_ed25519_standard
DynamicForward 1080 # 启用本地 Socks5 动态端口转发
PasswordAuthentication no
Host commando-win
HostName 192.168.95.155
User admin
Port 22
IdentitiesOnly yes
IdentityFile ~/.ssh/keys/id_ed25519_std
IdentityFile ~/.ssh/keys/id_ed25519_standard3.4 全局全局兜底配置:~/.ssh/conf.d/90-defaults.conf
为所有常规连接配置心跳保活与 ControlMaster(连接复用)。这是优化运维体验的核心:在主连接未断开时,后续新开终端将直接复用现有的 TCP 通道,无需重复触发硬件密钥认证或输入密码,实现秒级连接。
# 90-defaults.conf
Host *
# 启用心跳保活机制,防止因防火墙或路由器超时导致连接被动断开
ServerAliveInterval 30
ServerAliveCountMax 3
TCPKeepAlive yes
# 安全基线兜底
IdentitiesOnly yes
ForwardAgent no
AddKeysToAgent no
HashKnownHosts yes
# 多路复用 TCP 连接配置
ControlMaster auto
ControlPath ~/.ssh/controlmasters/%C
ControlPersist 10m
# 登录时展示基于 ASCII 码的主机指纹图形,以便直观防御中间人(MITM)劫持
VisualHostKey yes4 4. 总结与版本控制
通过上述重构,我们建立起了一个兼顾「高安全防御」与「丝滑运维体验」的现代 SSH 工作流。
在实际生产中,建议将 ~/.ssh/conf.d/ 目录纳入私有的 dotfiles 仓库进行版本控制。在多台工作站之间同步时,只需拉取该配置目录即可快速恢复完整的运维环境(注意:请务必将存放私钥的 keys/ 目录加入 .gitignore,切勿将私钥提交至代码仓库)。
5 参考与致谢
- 本文的防御性配置流与实战思路,灵感源自 Bilibili 红队笔记 的硬核技术分享:「红队笔记」红队基础设施SSH身份管理 - 红队视角讲解SSH密钥,Fido2硬件加密,SSH-Agent,SSH多路复用的最佳实践。