跳到正文
>_ITDITDWeb 安全平台

安全指南

不要把 root 密钥交给可能被入侵的环境:SSH 密钥的最小权限

你是否从 GPU 云的 pod、CI runner 这类『临时且可能被入侵的环境』向生产服务器登记了 SSH 密钥?一旦那把密钥泄露,别人就能以 root 权限进入你的生产环境。本站从运营视角讲清楚把密钥做成最小权限的思路,以及用非 root 用户+command 限制密钥『把能做的操作收窄到一个』的做法。

发布于 2026-06-11 更新于 2026-06-11 2 分钟阅读

适用对象:从 GPU 云的 pod、CI runner、一次性 VM 这类临时环境通过 SSH 连到生产服务器的人。这里不讲攻击手法,只讲把密钥做成最小权限、缩小爆炸半径这一件事。密钥分离这块地基,也请参考 安全底线清单

本站的视角:把临时环境当作『不可信任的前提』来对待

用完即弃的计算环境,加固往往被往后拖,是可能被入侵的地方。在那里放上通往生产的 root 密钥,就像把家门的备用钥匙扔在马路上。本站采用按主机使用不同密钥、收窄用途、不再需要的密钥立刻摘除的运营方式(→ 分开密钥把爆炸半径降到最小)。把密钥当作「漏了就全部打开的最重要资产」、而不是「方便的通行证」来对待,到头来才是最安全的。

✗ 临时环境放 root 密钥

临时环境被入侵 → 用那把密钥以 root 进入生产 → 文件、机密、其他服务全部都能够到。

○ command 限制的非 root 密钥

同一把密钥即使泄露,能做的也只有指定的那一条命令。shell 和转发都不行=损害封闭在一个操作里。

从一开始就把密钥的『可达范围』设计得小一些。泄露时的损害会大不相同。

为什么临时环境的 root 密钥危险

临时环境常因「反正马上就删」而省掉加固,在攻击者眼里是个容易下手的跳板。一旦那里有生产的 root 密钥,损害就会瞬间被放到最大。

root→全部
密钥泄露生产被整个夺走
用完即弃
临时环境加固被往后拖
复用
一把泄露暴露全部主机
最小权限
把操作收窄到一个损害也只有一个

举个例子,为了从临时立起来做计算的 pod 向生产作业,你把密钥登记进 root 的 authorized_keys。方便是方便,但那个 pod 一旦被入侵,攻击者就能用那把密钥以 root 权限进入生产。实际上,无论入口是 RCE 还是密钥泄露,最终「被盗的密钥把生产抽走」的构图都是一样的(相关:RCE 导致密钥被盗、被恶意扣费的故事)。

把密钥做成最小权限的 3 个步骤

别再「图方便就交出全部权限」,改成「把能做的事收窄到最小」。

1

摘掉临时环境的 root 密钥

不再使用的密钥,就从生产的 ~/.ssh/authorized_keys 里删掉。处于闲置状态删掉也没有影响。先把『放着不管』消除掉。
2

再次需要也不要回到 root

为生产作业重新登记时,不要用 root,而是新建一个专用的非 root 用户,把密钥登记给这个用户。万一泄露,可达范围也仅限于这个用户的权限。
3

改用『把能做的操作收窄到一个的密钥』

在 authorized_keys 的密钥行上加 command="..."restrict。即使能用这把密钥登录,也只能执行指定的那一条命令,端口转发和 shell 也能禁止。即使泄露,也能把损害封闭在那一个操作里。
# 在非root用户的 authorized_keys 里登记「把能做的操作收窄到一个的密钥」的示例
# 用这把密钥登录后,除指定命令外无法执行,转发、PTY 也被禁用
command="/usr/local/bin/deploy-pull",restrict ssh-ed25519 AAAA...rest-of-public-key deploy@ci

restrict 会把转发、agent 转发、PTY、X11 等一并禁用,command="..." 则把可执行的处理固定为一个。只允许拉取部署、只允许某个脚本——像这样按用途分别做出收窄到单一目的的密钥,是基本做法。

常见的(危险)结构

  • 从临时 pod / CI 把密钥登记到生产的 root
  • 用完的密钥不删、放着不管
  • 一把密钥在多台主机上复用
  • 到处散发能拿到全权 shell 的密钥

最小权限的结构

  • 连到生产只用非 root 用户
  • 密钥用command=「...」 restrict限定为一个操作
  • 按主机/用途分开密钥
  • 不再需要的密钥立刻从 authorized_keys 删除

把『复用密钥=最重要资产』来对待

一旦把密钥当成『方便的通行证』,就会不知不觉复用、忘记删除。反过来想,把它当作漏一把就全部打开的最重要资产来对待。按主机、按用途分开,临时环境里不放生产的密钥,放了就在用完后必定删掉。仅此就能斩断「一把泄露波及全局」这种最坏的连锁。

本站是怎么做的

本站按服务器使用专用密钥,不复用密钥。部署把接收方设为非 root 的专用用户,生产采用「不主动外出拉取,只负责接收」这种单向结构(→ 生产只负责接收)。不会从临时计算环境向生产留下长期常驻的密钥,只在需要时以最小权限连接。理由正如本文所述,就是为了在一处被入侵不会波及全局,预先把密钥的可达范围设计得小一些。

接下来读

FAQ

Q为什么把 root 密钥放进临时环境很危险?
A

GPU 云的 pod、CI runner 这类临时环境,因为用完即弃,加固往往被往后拖,所以可能被入侵。在那里放上通往生产服务器的 root 密钥,那个环境一旦被入侵,连同密钥一起,生产的 root 权限就会被夺走。原则是把临时环境当作『不可信任的前提』来对待,不在其中放置通往生产的 root 密钥。

Q如果还是想从临时环境连到生产呢?
A

不要回到 root,而是新建一个专用的非 root 用户,给这个用户登记一把『把能做的操作限定为一个的密钥』。在 authorized_keys 里加上 command=「...」 和 restrict,那么即使能用这把密钥登录,也只能执行指定的那一条命令。即使泄露,也能把损害封闭在那一个操作里。

Q密钥管理里最重要的原则是什么?
A

把『复用密钥=最重要资产』牢记于心,不要搭出漏一把就全被抽走的结构。按主机、按用途分开使用密钥,不再需要的密钥就从 authorized_keys 里删掉。这样就能防止一把的泄露波及全局。