安全高效的SSH最佳实践

SSH
基础设施
Author

Zumpyx

Published

June 9, 2026

随着管理的主机和云端资产不断增加,传统的单文件 ~/.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/config

2 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_sens

2.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_std

3 3. SSH 客户端配置模块化拆分

为了规避单配置文件带来的维护灾难,我们利用 Include 机制,按照数字前缀的优先级顺序加载子配置文件。

3.1 主入口配置:~/.ssh/config

主配置文件仅负责全局兼容性设定与子配置目录的分流。

# 忽略 macOS 专属配置项导致的未知错误(如 UserKeychain),确保跨平台兼容
IgnoreUnknown UserKeychain

# 引入子配置文件
Include ~/.ssh/conf.d/*.conf

3.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 VERBOSE

3.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_standard

3.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 yes

4 4. 总结与版本控制

通过上述重构,我们建立起了一个兼顾「高安全防御」与「丝滑运维体验」的现代 SSH 工作流。

在实际生产中,建议将 ~/.ssh/conf.d/ 目录纳入私有的 dotfiles 仓库进行版本控制。在多台工作站之间同步时,只需拉取该配置目录即可快速恢复完整的运维环境(注意:请务必将存放私钥的 keys/ 目录加入 .gitignore,切勿将私钥提交至代码仓库)。


5 参考与致谢