简体中文
员工离职后他的 SSH 密钥还散在几十台机器上?密钥轮换与权限回收怎么做
同事提离职,交接清单列了一串:账号、文档、密码箱、域名、云控制台。你一项项勾掉,最后总会卡在一种说不清的东西上——SSH 密钥。他的公钥可能塞在一台又一台服务器的 ~/.ssh/authorized_keys 里,而这些机器是谁、有多少台、他当年是不是还顺手加了几行别的,你心里没底。密码能改、能禁用,密钥这种东西一旦散出去,就很难确认"他还有没有入口"。这篇文章不教你怎么配服务,只讲清一件事:密钥为什么会散、该怎么判断自己在哪个层面做轮换和回收,才能让"离职"这件事不再留下一个没人数的清的后门清单。
密钥之所以会散,是因为 authorized_keys 天生是分散的
SSH 的免密登录,靠的是把公钥塞进目标机器的 ~/.ssh/authorized_keys。这个文件存在于每一台服务器的 每一个账户下,根上没有哪台"主服务器"登记过"全公司一共有多少把公钥、谁持有哪一把"。你给新同事开通访问的方式,大概率是把他刚生成的公钥一行行追加到各台机器的 authorized_keys 里:
ssh-keygen -t ed25519 -C "zhangsan@workstation"
ssh-copy-id -i ~/.ssh/id_ed25519.pub zhangsan@10.0.0.12前一行在他自己的电脑上生成密钥对,后一行把他的公钥写进目标机。换成十台机器,就是十次 ssh-copy-id 或十次手工粘贴。规模小的时候这没问题,但它埋下了一个结构性的坑:公钥是"点对点"分发进每台机器的,没有任何一份清单记录"谁在哪些机器有入口"。 资产本身越像一台台手工养起来的"宠物机"(pet),这个坑就越深;只有当机器变成用配置管理批量交付的"牲口机"(cattle),公钥才可能跟着一份源码清单一起被纳管。
所以问题不是"忘了登记",而是这套机制在设计上就没有中央登记点。想要回收,你就得回到每一台机器去翻 authorized_keys——这正是离职场景里最反直觉的痛点:你以为是一个"账号"要关,实际可能是几十台机器上散落的几十行公钥。
离职时你面对的,是一串认不出主人的公钥
打开任意一台机器的 ~/.ssh/authorized_keys,你看到的大概率是这样一堆东西:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK3q9...zhang@..
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... ubuntu@backup
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL7mZ... (no comment)每一行是一个公钥,末尾那个 zhang@ 或空着不写的是注释(comment),它只是当年生成时的随手备注,不是任何身份校验。SSH 认证时比对的只有中间那一长串 base64 编码的钥匙本体,注释写不写、写错没写错,都不影响能不能登录。
这就带来离职交接最难受的一刻:你盯着这串 base64,想判断"哪一行是离职那位同事的",靠的只能是注释里的字符串碰运气。注释写的是工作邮箱那还好认,写的是 zhang@、macbook、甚至干脆没写,你就只能靠"这一行我从来没见过"来猜。更要命的是共享账户——一台服务器就一个 ubuntu 或 root,五六个人的公钥全塞在同一个账户里,你真要"删掉某个人",没法把他的存在和账户一并抹掉,只能从一堆公钥里挑。
这说明了一个关键判断:authorized_keys 能告诉你"有哪些钥匙",却告诉不了你"每把钥匙属于谁、现在还算不算数"。 身份信息和访问入口是脱节的,而脱节的代价,在有人离职的那一刻集中爆发。
轮换和撤销,其实是两件事
很多人把"密钥轮换"当成一个动作:把旧的删掉、生成新的。但拆开看,离职场景里你要处理的其实是两件目标不同的事:
| 场景 | 面对的问题 | 要做的动作 |
|---|---|---|
| 私钥疑似泄露 | 钥匙本身可能已经不在持有人手里 | 让密钥失活:吊销公钥、回收私钥持有权,越快越好 |
| 人员离职 | 钥匙没坏,但持有人不该再有入口 | 撤销访问:让这个人的公钥在每一台机器上失效 |
私钥泄露时,你担心的是"这把锁已经被配了钥匙",所以要做的是一把一把找到这把公钥对应的门,全都换锁;人员离职时,锁和钥匙都还完好,你要做的是"这个人手里的钥匙,从此打不开任何一扇门"。两者最终都会落到同一个动作——把对应的公钥从 authorized_keys 里删掉或替换——但因为动机不同,紧迫程度和范围判断完全不同。
泄露场景还有个容易被忽略的细节:删除公钥只阻止"之后再用这把私钥登录",挡不住已经建立的连接。 如果有人此刻正挂着那个 SSH 会话,删掉公钥不会把会话踢下线。真要立刻断掉,得配合终止对应进程、检查是否有 tmux/screen/nohup 留下的长驻进程、以及是否有人在 authorized_keys 之外借 authorized_keys2 或其它账户绕了一圈。撤销访问从来不是"删一行"那么干净利落。
判断你该在哪个层面做这事
落到实操,关键不是"选哪个工具",而是先想清楚你处在这条光谱的哪一段——它决定了你该用多大的力气、把轮换和回收放在什么层面:
- 两三个人、三五台机器:逐台翻 authorized_keys 完全够用。你记得清每一台机器,公钥数量一只手数得过来,离职时列个清单逐台过一遍,成本可接受。
- 机器开始用配置管理批量交付:把公钥清单放进配置管理(或一台跳板机的授权文件)里,人员变动时改的是那份源头清单,再统一下发。这时"回收"从"逐台战斗"变成"改一处、推全部"。
- 需要可审计、能对上人、登录动作有迹可循:授权不再以"把公钥写进机器"的形式存在,而是收敛到中间层——用户手里不再持有能直接进机器的钥匙,登录都经由统一入口按角色鉴权。人员离职时,在入口处把他的账号或授权一关,全线失效,还能拿到他过去都碰过什么的记录。
这段光谱对应一个朴素的结论:你越是依赖"把钥匙直接发给每个人",离职时回收的成本就越高,漏网的概率也越大;你越早把"访问"收敛到少数几个可集中吊销的节点,人员变动就越不痛。 这和选不选某个具体产品无关,是运维结构本身的走向。
方案落地
如果你的团队已经走到需要"能对人、可审计、集中吊销"的那一段,堡垒机是这条光谱自然的一个落点:服务器的凭据托管在中间层,用户通过统一入口按授权访问,授权、登录、操作都留有记录。以 Next Terminal 为例,它把资产统一登记(参见资产管理)、经由 SSH 网关 或 SSH 代理服务器 做统一接入,流程与同类产品大同小异,换成别的也能照搬。真正让"离职"变轻的不是某款软件,而是你有没有把散落的钥匙收回到一个能一口关上的地方——配合二次认证(见 OTP 一次性密码)与按角色授权(见用 Next Terminal 满足合规与审计要求),"某天某人离职"就从一次逐台排查,退化成一次开关操作。