LazyCat SSH 是一套轻量级的 SSH 基础设施管理工具,旨在通过 SSH 证书认证(SSH CA) 简化多服务器的访问控制。
它解决了传统 authorized_keys 管理痛点:
- 无需分发公钥:服务器不再需要存储每个人的公钥。
- 配置自动同步:通过 Gist 集中管理服务器列表,团队成员一键同步 SSH Config。
- 安全性更高:证书支持有效期(如 12 小时),过期自动失效,无需手动吊销。
本套件包含三个独立脚本,分别对应三种角色:
| 脚本 | 路径 | 角色 | 部署位置 | 功能 |
|---|---|---|---|---|
| CA 管理端 | ssh/ca |
证书颁发者 | 管理员本地 / 堡垒机 | 生成 CA 根密钥,签发用户证书 |
| Node 被控端 | ssh/node |
被访问资源 | 生产/测试服务器 | 配置 sshd 信任 CA,允许持证登录 |
| Client 控制端 | ssh/client |
访问发起者 | 开发者电脑 | 同步服务器配置,申请/续期证书 |
目标:生成一对 CA 密钥(私钥签发证书,公钥下发给服务器)。
在 管理员电脑 或 中央堡垒机 上运行:
sudo bash -c "$(curl -fsSL https://ep.nekro.ai/e/KroMiose/LazyCat/main/ssh/ca/lazycat-ssh-ca.sh)"- 选择
1) 初始化 CA。 - 脚本会在
~/.lazycat/ssh-ca生成 CA 密钥对。私钥请妥善保管!
目标:让服务器信任该 CA 签发的证书。
-
获取安装命令: 在 CA 管理脚本中,选择
3) 查看 Node 端配置提示。 Copy 出来的那行命令包含了当前的 CA 公钥。 -
在服务器执行: 登录到你的目标服务器(如 Ubuntu/CentOS),粘贴并执行该命令:
# 示例(请务必使用 CA 脚本生成的实际命令) sudo bash -c "$(curl -fsSL ...)" -- "ssh-ed25519 AAAA..."
该操作会自动修改
/etc/ssh/sshd_config添加TrustedUserCAKeys并重载 sshd。
目标:同步连接列表,并获取证书进行登录。
管理员需创建一个 Secret Gist(gist.new)。文件名不要求固定(建议:lazycat-ssh.yaml),内容示例:
version: 1
# 不带后缀的主 alias 默认走哪条线路:lan / wan / tun(默认 lan)
default_route: lan
# CA 签发相关配置
ca:
ssh_host: my-bastion # 能够 SSH 直连到 CA 管理端的 Host 别名(需提前配好 ~/.ssh/config 或 DNS)
ca_key_path: ~/.lazycat/ssh-ca/lazycat-ssh-ca # CA 私钥在远端的路径
principals: root,ubuntu # 证书允许登录的目标用户名
validity: 12h # 证书有效期
# 服务器列表
hosts:
prod-db:
# 只要配置了 lan_host/wan_host/tun_host 之一,就会进入“多线路模式”,自动生成:
# - prod-db(不带后缀,受 default_route 影响)
# - prod-db-lan / prod-db-wan / prod-db-tun(按你配置的线路生成)
lan_host: 192.168.1.10
lan_port: 22
wan_host: prod-db.example.com
wan_port: 2222
user: root
web-01:
host: 10.0.0.5 # 兼容旧字段(等同 wan_host);只配置 host 时不会生成 -lan/-wan/-tun
user: ubuntu
via: prod-db # 支持 ProxyJump 跳板说明:
- 不带后缀的
<alias>会按default_route的优先级选择“已配置的线路”生成(不会做网络探测自动切换)。 - 优先级规则:
default_route: lan:lan > tun > wandefault_route: wan:wan > tun > landefault_route: tun:tun > wan > lan
via的语义是“必要时可通过跳板访问”,默认不会干涉直连:- 如果你访问的线路本身存在(例如配置了
lan_host且你ssh <alias>-lan),则不会自动添加跳板(除非显式配置了lan_via/wan_via/tun_via)。 - 如果你访问的线路不存在、但配置了
via(例如仅配置lan_host,你却ssh <alias>-tun),脚本会自动生成“通过跳板访问”的别名:- 目标 HostName 会回退到可用线路(优先
lan > tun > wan) - ProxyJump 会优先选择
via-<线路>(例如via-tun),否则回退via
- 目标 HostName 会回退到可用线路(优先
- 想强制某条线路总走跳板:使用
lan_via/wan_via/tun_via显式指定(例如lan_via: bastion-lan)。
- 如果你访问的线路本身存在(例如配置了
- 为了避免同域名/同端口复用导致
known_hosts冲突,脚本会为每个 Host 自动写入HostKeyAlias <alias>;如果需要清理某个 alias 的旧指纹,可执行ssh-keygen -R <alias>(例如:ssh-keygen -R your-server-wan)。
在开发者电脑上运行:
bash -c "$(curl -fsSL https://ep.nekro.ai/e/KroMiose/LazyCat/main/ssh/client/lazycat-ssh.sh)"- 运行
lazycat-ssh。 - 选择
1) Gist 引导与配置-> 填入 Gist URL。 - 选择
2) 从 Gist 同步 SSH 配置。- 脚本会自动读取你选择的 YAML 文件并生成
~/.ssh/config.d/lazycat.conf。 - 脚本会自动 SSH 连接到
ca.ssh_host申请证书。
- 脚本会自动读取你选择的 YAML 文件并生成
完成后,你可以直接登录:
ssh prod-db无需输入密码,也无需手动管理 key。
证书默认有效期较短(如 12h)。过期后:
- 手动续期:运行
lazycat-ssh renew-certs。 - 自动续期:运行
lazycat-ssh-> 选择5) 安装后台自动续期(支持 macOS Launchd / Linux Systemd)。
若自动续期似乎未生效,可按以下方式排查:
-
一键查看状态与最近日志(推荐)
lazycat-ssh renew-status
会输出:是否已安装定时任务、launchd/systemd 状态、以及最近一次续签的标准输出/错误日志路径与内容。
-
macOS 手动排查
- 是否已加载 LaunchAgent:
launchctl list | grep lazycat
或(macOS 13+ 用户域):
launchctl list gui/$(id -u) | grep lazycat - 续签脚本的标准输出与错误会写入:
~/.lazycat/ssh/renew.log~/.lazycat/ssh/renew.err.log
可直接查看:
tail -50 ~/.lazycat/ssh/renew.log、cat ~/.lazycat/ssh/renew.err.log
- 是否已加载 LaunchAgent:
-
Linux (systemd) 手动排查
- 查看 timer 是否在跑:
systemctl --user status lazycat-ssh-renew.timer - 查看最近续签日志:
journalctl --user -u lazycat-ssh-renew.service -n 50
- 查看 timer 是否在跑:
-
先确认手动续签是否正常
若后台续签失败,多半是环境问题(网络、SSH 到 CA 失败等)。先执行一次:
lazycat-ssh renew-certs
看终端报错,再根据错误修复(如 CA 不可达、meta.env 缺失等)。
所有脚本均提供一键卸载/回滚功能:
- Node 端:再次运行安装脚本 -> 选择
3) 移除配置(回滚 sshd_config)。 - Client 端:运行
lazycat-ssh-> 选择8) 卸载。
Q: Client 端如何连接 CA 服务器?
A: Client 脚本通过标准 SSH 连接 CA 服务器来申请签名。因此,Client 机器必须能够通过 SSH key (authorized_keys) 登录到 CA 服务器所在的机器(即 ca.ssh_host)。这是信任链的根源。
Q: "principals" 是什么?为什么需要配置它?
A: principals 是 SSH 证书中的权限白名单。它指定了持有该证书的用户允许以什么系统账号登录目标服务器。
- 例如配置
principals: root, ubuntu:表示你可以执行ssh root@host或ssh ubuntu@host。 - 如果你尝试
ssh db_admin@host,即使证书有效,服务器也会拒绝登录,因为db_admin不在证书的授权名单里。 这防止了用户持有证书后随意登录任何高权限账号。
Q: 支持 Windows 吗? A: 目前仅支持 Linux 和 macOS (Bash)。