SSH 密钥轮换是安全运维中的重要实践。本文将介绍为什么需要轮换 SSH 密钥,以及如何实现安全、便捷的密钥轮换方案。

为什么要轮换 SSH 密钥

长期使用同一个 SSH 密钥会带来以下风险:

  1. 密钥泄露风险:密钥可能通过各种途径泄露(备份泄漏、离职人员带走等)
  2. 密钥老化:长时间使用的密钥可能被暴力破解或通过其他方式破解
  3. 合规要求:许多安全标准和合规要求强制定期更换认证凭据
  4. 最小权限原则:定期轮换可以确保只有当前需要访问的用户持有有效密钥

手动轮换流程

1. 生成新密钥

1
2
3
4
5
# 使用 Ed25519 算法(推荐)
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_new -C "your-email@example.com"

# 或使用 RSA(如果需要兼容旧系统)
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_new -C "your-email@example.com"

2. 分发公钥到服务器

1
2
3
4
5
6
7
# 方式一:使用 ssh-copy-id
ssh-copy-id -i ~/.ssh/id_ed25519_new.pub user@server

# 方式二:手动添加到远程服务器的 authorized_keys
ssh user@server "mkdir -p ~/.ssh && chmod 700 ~/.ssh"
scp ~/.ssh/id_ed25519_new.pub user@server:~/.ssh/
ssh user@server "cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

3. 验证新密钥可登录

1
2
# 测试新密钥连接
ssh -i ~/.ssh/id_ed25519_new user@server

4. 删除旧密钥

确认新密钥正常工作后,删除旧的公钥和本地私钥:

1
2
3
4
5
# 在服务器上删除旧公钥
ssh user@server "sed -i '/old-key-comment/d' ~/.ssh/authorized_keys"

# 本地删除旧私钥
rm ~/.ssh/id_rsa_old ~/.ssh/id_rsa_old.pub

使用 SSH 证书实现自动轮换

SSH 证书认证是一种更优雅的密钥管理方案。核心思想是引入一个 SSH CA(Certificate Authority),由 CA 签署用户证书,证书可以设置有效期,过期自动失效。

1. 创建 SSH CA

1
2
# 创建 SSH CA 密钥(建议存储在专用机器上)
ssh-keygen -t ed25519 -f /path/to/ssh_ca -C "SSH-CA"

这会生成两个文件:

  • /path/to/ssh_ca - CA 私钥(必须严格保管)
  • /path/to/ssh_ca.pub - CA 公钥(需要分发到所有服务器)

2. 配置服务器信任 CA

在每台服务器上,将 CA 公钥添加到 authorized_keys 文件的特殊位置(而不是用户目录下):

1
2
3
4
5
6
7
8
# 在服务器的 /etc/ssh/ 目录下创建 CA 公钥目录
sudo mkdir -p /etc/ssh/ca_keys

# 复制 CA 公钥到服务器
sudo cp /path/to/ssh_ca.pub /etc/ssh/ca_keys/

# 编辑 SSH 配置
sudo vim /etc/ssh/sshd_config

添加以下配置:

1
TrustedUserCAKeys /etc/ssh/ca_keys/ssh_ca.pub

重启 SSH 服务:

1
sudo systemctl restart sshd

3. 签署用户证书

用户生成密钥后,由 CA 使用私钥签署证书:

1
2
# CA 服务器执行:签署用户公钥
ssh-keygen -s /path/to/ssh_ca -I "user-identity" -n username -V "+52w" user_key.pub

参数说明:

  • -s:指定 CA 私钥
  • -I:证书标识符
  • -n:允许的用户名(Principals)
  • -V "+52w":证书有效期(52 周)

执行后会生成 user_key-cert.pub 证书文件。

4. 使用证书登录

用户需要同时提供私钥和证书:

1
ssh -i user_key user_key-cert.pub username@server

或者在 SSH 配置中指定:

1
2
3
4
5
Host server
    User username
    HostName server.example.com
    IdentityFile ~/.ssh/user_key
    CertificateFile ~/.ssh/user_key-cert.pub

5. 证书过期自动失效

证书过期后自动失效,无需手动撤销。通过设置较短的有效期(如 1 周或 1 个月),可以实现"定期自动失效"。

用户只需在证书过期前重新申请签名即可继续使用。

批量轮换脚本

对于需要管理大量服务器的场景,可以使用脚本自动化密钥轮换。以下是一个完整的轮换脚本示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/bin/bash
# SSH 密钥自动轮换脚本

set -e

# 配置参数
SSH_DIR="${HOME}/.ssh"
CA_KEY="/path/to/ca_key"  # SSH CA 私钥路径
SERVERS_FILE="/path/to/servers.txt"  # 服务器列表文件
KEY_COMMENT="$(whoami)@$(hostname)-$(date +%Y%m%d)"
VALIDITY="52w"  # 证书有效期

# 1. 生成新的用户密钥对
echo "正在生成新的 Ed25519 密钥..."
KEY_NAME="id_ed25519_$(date +%Y%m%d)"
ssh-keygen -t ed25519 -f "${SSH_DIR}/${KEY_NAME}" -N "" -C "${KEY_COMMENT}"

# 2. 使用 CA 签署用户公钥生成证书
echo "正在签署用户证书..."
CERT_FILE="${SSH_DIR}/${KEY_NAME}-cert.pub"
ssh-keygen -s "${CA_KEY}" -I "${KEY_COMMENT}" -n "$(whoami)" -V "+${VALIDITY}" \
    "${SSH_DIR}/${KEY_NAME}.pub" - > "${CERT_FILE}" || {
    echo "证书签署失败"
    exit 1
}

# 3. 批量部署证书到服务器
echo "正在部署证书到服务器..."
while read -r server; do
    if [[ ! "$server" =~ ^#.*$ ]] && [ -n "$server" ]; then
        echo "部署到: $server"
        scp "${CERT_FILE}" "${server}:~/.ssh/authorized_keys" 2>/dev/null || \
        echo "警告: 部署到 $server 失败"
    fi
done < "${SERVERS_FILE}"

# 4. 更新 SSH 配置文件
echo "更新 SSH 配置..."
cat >> "${SSH_DIR}/config" <<EOF

# 新证书配置 - $(date)
IdentityFile ~/.ssh/${KEY_NAME}
CertificateFile ~/.ssh/${KEY_NAME}-cert.pub
EOF

echo "密钥轮换完成!新证书有效期: ${VALIDITY}"

使用说明:

  1. 创建服务器列表文件 servers.txt,每行一个服务器地址:

    1
    2
    3
    
    user1@server1.example.com
    user2@server2.example.com
    # 注释行
    
  2. 运行脚本:

    1
    2
    
    chmod +x rotate_ssh_key.sh
    ./rotate_ssh_key.sh
    

最佳实践总结

实践 说明
使用现代算法 推荐 Ed25519 或 ECDSA,避免 RSA
保护私钥 使用强密码短语加密私钥
使用证书认证 简化多用户、多服务器环境的管理
设置合理有效期 根据安全需求设置证书有效期(建议 1-12 个月)
定期审计 定期检查和清理不再使用的 SSH 密钥
及时吊销 员工离职时立即撤销其 SSH 访问权限

总结

SSH 密钥轮换是保障系统安全的重要措施。通过采用 SSH 证书认证方案,可以实现:

  • 证书过期自动失效,无需手动撤销
  • 灵活设置有效期,满足不同安全级别需求
  • 简化大规模环境下的密钥管理

结合自动化脚本,可以将密钥轮换的运维成本降到最低。


参考来源