花拾录
← 返回知识库

往 root 的 authorized_keys 加公钥不生效:它是软链到平台管理的文件

云计算 / 运维导入2026/09/220 阅读0 评论

你在一台由虚拟化平台托管的机器上配置 SSH,想把新机器的公钥加到 root 的授权列表里,好免密登录。你把公钥 cat >> ~/.ssh/authorized_keys 追加上去,保存。然后去登录——还是让你输密码,公钥认证没用。

现象

表现是:你明明把公钥写进了 root 的 ~/.ssh/authorized_keys,cat 出来也能看到那一行,但用对应私钥登录时:

Permission denied (publickey,password).

公钥认证被跳过,只能退回密码。更诡异的是,过一阵子再 cat 一下,你加的那行不见了——像是被谁悄悄删掉了。

根因

先看一个命令的输出:

ls -l /root/.ssh/authorized_keys

你很可能会看到类似这样一行:

/root/.ssh/authorized_keys -> /etc/pve/priv/authorized_keys

那个 -> 说明它是个软链接(symlink),真实文件在别处,比如在平台自己的管理目录下(如 /etc/pve/...)。

这就解释了两个现象:

  • 你往 authorized_keys 里 cat >>,写是写进去了,但写的是软链指向的真实文件——这本身没错,不过……
  • 这个真实文件是被平台(或某个守护进程/模板机制)维护的。平台在重启、同步、重建配置时,会按它自己掌握的内容重新生成这个文件,把你手动加的那行覆盖掉。于是你看到"加了却不生效",过一会儿"又被删了"。

也就是说,你和一个自动化机制在抢同一个文件。它按自己的数据源重写,你的手写内容自然保不住、也不稳定。

解决

既然文件归平台管,就走平台自己的机制来加,别手改。

做法一:用平台的密钥管理功能。

Proxmox VE 在数据中心(Datacenter)级别有 SSH 密钥管理界面,把你的公钥填进去,平台会在同步时把它下发到各节点的 authorized_keys。这样加进去的密钥是被平台认账的,不会被覆盖。

做法二:直接走平台的认证方式。

如果这台机器本来就是平台统一认证的(比如通过平台登录、或走平台下发的密钥),那"往 root 里塞公钥"本身可能就不是你要走的路——用平台给的凭据即可。

做法三:如果你确实要接管这个文件。

那就得先搞清楚是谁在维护它——找到那个会重写它的服务/定时任务,在它之外换一条真正属于你的路径。比如给一个普通用户配置独立的 ~/.ssh/authorized_keys(如果那个用户不受平台托管),或者弄清平台的同步逻辑后再决定怎么共存。不要不搞清楚维护方就硬写,那只会反复被覆盖。

验证是否生效:

# 看这个文件到底指向哪
ls -l /root/.ssh/authorized_keys
readlink -f /root/.ssh/authorized_keys

延伸与预防

这条坑给出的是排错时的一条通用信号:

看到软链接,就要立刻意识到"真实文件在别处,而且在别处有别的东西在维护它"。

软链往往意味着"这个路径只是个别名的展示层",真正的写入目标、以及谁在写它,都在链路后面。不顺着链路查下去就动手改,等于蒙着眼睛跟另一个自动化进程抢文件。

同类场景其实不少:

  • 系统里的配置文件被某个"模板 + 渲染"机制(如 Ansible、cloud-init、平台面板)生成,手改会被下次同步覆盖;
  • 容器里的某个路径是 bind mount,改了容器内文件其实改的是宿主机文件;
  • /etc/resolv.conf 被网络管理器托管,手改重启就没了。

预防办法一致:动手改一个"看起来普通"的文件之前,先 ls -l、readlink -f 看它是不是软链、是不是挂载点;然后再问一句"谁在管这个文件"。把这两步当成本能,能省掉很多"我改了它为什么自己变回去"的困惑。

评论(0)

  • 还没有评论,来抢沙发~

相关文章