SSH 登陆与证书化实践

目录

  1. 原理速记
  2. ssh-copy-id —— 一键分发公钥
  3. ssh-agent —— 私钥只解锁一次
  4. 小团队高频变更?上 SSH CA
  5. 最小实验环境
  6. FAQ
  7. 结语

原理速记

  1. 每个用户在本地生成一对 非对称密钥

    1
    ssh-keygen -t ed25519 -C "alice@example.com"

    • 私钥 ~/.ssh/id_ed25519 仅保存在本机
    • 公钥 ~/.ssh/id_ed25519.pub 追加到远端用户 ~/.ssh/authorized_keys 即可完成免密登陆

  2. authorized_keys 会被 CM/定时任务覆盖时,可在服务端 /etc/ssh/sshd_config 启用第二个文件:

    1
    AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2

    将个人公钥写入 authorized_keys2,与配置管理系统互不干扰。修改后执行

    1
    sudo systemctl reload sshd

ssh-copy-id —— 一键分发公钥

1
ssh-copy-id alice@serverA

底层做的事:先正常 ssh 登陆,再把本地 ~/.ssh/id_*.pub 追加到远端的 authorized_keys
• 优点:一行命令,无需 echo >>
• 缺点:一次只能处理「一台主机 & 一位用户」,批量场景捉襟见肘


ssh-agent —— 私钥只解锁一次

1
2
eval "$(ssh-agent -s)"        # 启动 agent
ssh-add ~/.ssh/id_ed25519 # 加载私钥

• 首次输入私钥密码后即缓存在内存,后续连接无需重复输入
~/.ssh/config 中加入 AddKeysToAgent yes 可自动加载
• macOS、Windows (Pageant/WSL) 均提供图形化托管


小团队高频变更?上 SSH CA

3.1 痛点

N 台机器 × M 个人
• 传统模式:需维护 N × M 条公钥;新成员/离职/新服务器 → 全量同步,极易遗漏
• 权限收敛粒度有限,仅靠「加/删整行公钥」

3.2 核心思路

  1. 由管理员创建一对 CA 私钥 / CA 公钥
  2. CA 公钥 下发到所有服务器,并在 sshd_config 中信任之
  3. 用户公钥不再直接进服务器,而是先由 CA 私钥 签成 证书 (*-cert.pub)
  4. 用户本地携带「私钥 + 证书」即可登陆,服务器负责校验证书是否由受信 CA 签发且仍在有效期内

3.3 一次性基础设施

管理员机:

1
2
3
4
5
6
7
8
9
# 1) 生成 CA
ssh-keygen -t ed25519 -f ~/ca_root -C "company-user-ca"

# 2) 把公钥下发并写入 sshd_config
for h in serverA serverB; do
scp ~/ca_root.pub root@$h:/etc/ssh/ca_root.pub
ssh root@$h "echo 'TrustedUserCAKeys /etc/ssh/ca_root.pub' >> /etc/ssh/sshd_config \
&& systemctl reload sshd"
done

3.4 日常增删用户

新增 bob,有效期 90 天,只允许以账号 bob 登陆:

1
2
3
4
5
6
7
ssh-keygen -s ~/ca_root        \        # CA 私钥
-I bob \ # 证书 ID
-n bob \ # principals(允许的登录名)
-V +90d \ # 有效期
-z 20250623001 \ # 序列号,可用于撤销
~/.ssh/bob.pub # 用户公钥
# 产出文件: ~/.ssh/bob-cert.pub

发送 bob-cert.pub 给用户,用户侧配置

1
2
3
4
5
# ~/.ssh/config
Host *.corp
User bob
IdentityFile ~/.ssh/bob # 私钥
CertificateFile ~/.ssh/bob-cert.pub # 证书

至此无需再触碰服务器。若要收回权限,只需把序号 20250623001 加入服务器的 RevokedKeys 列表并 reload sshd。

3.5 成本对比

10 台机器 × 10 名成员
• 传统:100 次写 authorized_keys
• CA:下发 1 个 CA 公钥 到 10 台机器 + 签 10 份证书,共 20 次操作
后续「加人/加机」都只需 1 步,线性成本


最小实验环境(Hands-on)

以下步骤可在两台虚拟机里 3 分钟跑通。

4.1 目录规划

1
2
mkdir -p ~/ssh-ca/{ca,users,hosts}
cd ~/ssh-ca

4.2 生成两类 CA(可选)

1
2
3
4
5
# 用户 CA:用于给人签证书
ssh-keygen -t ed25519 -f ca/user_ca -C "User CA Key"

# 主机 CA:用于给服务器自己签 Host 证书(可选)
ssh-keygen -t ed25519 -f ca/host_ca -C "Host CA Key"

目录结构

1
2
3
4
5
6
.
├── ca
│ ├── host_ca host_ca.pub
│ └── user_ca user_ca.pub
├── hosts # 主机公钥/证书存放处
└── users # 用户公钥/证书存放处

4.3 给某台服务器签 Host 证书(可选)

1
2
3
4
5
6
7
8
9
10
11
# 1) 服务器上生成自身 host key(如已存在可跳过)
sudo ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N '' -C 'host ed25519 key'

# 2) 用 host_ca 私钥签发
sudo ssh-keygen -s ~/ssh-ca/ca/host_ca \
-I host_10.10.90.105 \
-h \
-n 10.10.90.105 \
-V '+52w' \
/etc/ssh/ssh_host_ed25519_key.pub
# 产出 /etc/ssh/ssh_host_ed25519_key-cert.pub

客户端将 ca/host_ca.pub 添入 ~/.ssh/known_hosts@cert-authority 记录后,即可基于证书校验主机身份,彻底告别 “yes/no” 指纹确认。

4.4 给用户签证书并登陆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# (管理员机)收到 bob 的 id_ed25519.pub
ssh-keygen -s ca/user_ca -I bob -n bob -V +1d users/bob.pub
# 产出 users/bob-cert.pub

# (bob 本地)
mv users/bob-cert.pub ~/.ssh/
echo '
Host server?.demo
User bob
IdentityFile ~/.ssh/id_ed25519
CertificateFile ~/.ssh/bob-cert.pub
' >> ~/.ssh/config

ssh server1.demo # 免密

FAQ

Q1 如果同一用户需要不同权限,是否要多张证书?
A 是。建议一个权限集合对应一张证书,通过 -n dev,gpu 等 principals 控制。登陆时 OpenSSH 会自动匹配多张证书,无需手动 -o CertificateFile=

Q2 如何收回某位成员的 admin 权限但保留 gpu
给他重新签一张不含 admin 的新证书,并把旧证书的序列号写入服务器端 RevokedKeys

Q3 证书吊销如何自动分发?
用你现有的 CM/Ansible/Salt 维护一份集中式 ssh_ca_revoked 文件,并在 sshd_config 中:

1
RevokedKeys /etc/ssh/ssh_ca_revoked

配合 CI/CD 即可秒级下发、热更新。

Q4 如何自动化签发?
写一个 REST/CLI 的 “CA 服务”:
• 入参:用户公钥 + 角色组(dev/gpu/test/tmp/long-term…)
• 出参:同名 *.pub-cert.pub
再配合 Jenkins/GitLab Runner 即可做到“一键申请、一键续期”。


结语

SSH CA 不是新技术,却极易被忽视。只需一次性部署,即可:

• 将公钥管理从 O(N×M) 降至 O(N+M)
• 对成员/主机实现「秒级生效、秒级撤销」
• 精细化权限(principals + 有效期)与审计(证书序列号)

希望本文能帮你在下一轮服务器扩容或团队变动时,减少 80%+ 的重复劳动。Happy Hacking!

作者

zion h4

发布于

2025-06-23

更新于

2025-06-23

许可协议

评论