一把被限定在单一身份与狭窄权限范围内的 SSH 密钥。

SSH 密钥卫生,主要是限制密钥能干什么

SSH 密钥很方便,而方便正是在不知不觉中失控的原因。实践上的关键纪律并不是少生成几把密钥,而是让每把密钥都成为有清晰用途、有限生命周期、并且能在"谁被允许做什么"的文件里留下记录的一个具名身份。 一把密钥应被当作一个身份 一把 SSH 密钥应当能读作一个身份,而不是一句无密码的便利。给它起名:为了它属于谁、为什么存在,而不是为了它恰好躺在那台笔记本;给它一个简短的注释,并在你的工具支持时给私钥配一个口令,让一份只拿到了文件的人无法直接使用。一把「一看就知道属于谁、可以做什么」的密钥,能让后续的运维者不假思索就应用最小权限原则——这正是「上了锁的凭据」和「一堆谁也认不出的无名钥匙」之间的分水岭。 范围才是关键 范围才是密钥的要害。尽量让一把 key 只能碰到它该碰的东西:在服务端,通过账户与 authorized_keys 的设置,只接收该接收的 key,并限制每把 key 具体能做哪些——别一股脑把整台机器的大权交给一个起自自动化的角落。遇到自动化用途,更要按命令、源或目录把它钉死在一个边界内;一把范围被钉死的 key,在泄漏时,泄漏时,损失的也只是「这个被定义好的边界」,而不是一把「每一扇门都能开」的总钥匙。 轮换与审计线索 旧钥匙不会自己走。一套轮换的节奏,才是让清单长久诚实的办法:删掉已经没人再用的 key,把剩余的交实际负责人重新签发,并过一段时间再确认一次——「现在被接受的这些 key,是不是真的对应我要的那些人、那些用途」。authorized_keys 本身,就是把这份「谁允许做什么」变成可复核的文件的实体。这样一个定期、便宜又明确的检查,抵得上一百次在事故后茫然翻找。 坏掉的样子 没有口令的私钥,会让每一个副本都变成一次登录。入职克隆笔记本、把个人配置推到共享仓库、备份软件同步家目录,都会顺带复制 ~/.ssh。只要有人能读到其中一份,就能立刻登录,而服务端日志分辨不出小偷和主人。全程没有任何口令提示,故障是静默的,往往要等日志里出现陌生地址才会被发现。 长期残留的 authorized_keys 条目,是另一种同样安静的失效。工程师离职、合作到期、定时任务下线,公钥却还留在服务器上,因为没人负责清理。几个月后,那一行被遗忘的记录依然有效,而且大多没有 from=、command= 这类限制,等于没有使用边界。只发新钥而不删旧钥的轮换,每转一圈都在扩大攻击面。 第三种失效是算法老旧。ssh-dss 和短长度的 ssh-rsa 在宽松配置的服务端上依然能登录,尽管主流建议早已转向 Ed25519。连接一旦成功就不会告警,而攻击者截获的每次握手,都能在弱算法上拿到大得多的杠杆。正确做法是生成新类型密钥并删掉旧行,而不是让两种长期并存。 第四种是代理转发劫持。用 ssh -A 登录时,本地代理套接字会暴露到远端主机,有足够权限的人可在会话期间让你的代理替他签名。私钥文件纹丝未动,登录却以你的名义扩散到更多主机。症状是:横向移动发生了,现场却找不到被盗密钥,只剩转发打开期间产生的一串签名。 快速验证 把下面的脚本保存为 ssh_audit.py,运行 python3 ssh_audit.py。它只用 Python 标准库,只读当前用户 ~/.ssh,不做任何修改;没有密钥文件的机器报告 SKIP 而非报错,新机器也能干净跑完。 ...

七月 6, 2026 · 3 分钟 · XB Field Notes