如何在无法使用 sudo 的情况下恢复损坏的 sudoers 文件?

如何在无法使用 sudo 的情况下恢复损坏的 sudoers 文件?

我收到以下错误sudo

$ sudo ls
sudo: /etc/sudoers is owned by uid 1000, should be 0
sudo: no valid sudoers sources found, quitting
sudo: unable to initialize policy plugin

当然chown,如果root不使用sudo.我们的帐户也没有密码root

老实说,我不知道系统是如何陷入困境的,但现在轮到我来解决它了。

通常我会启动进入恢复模式,但系统是远程的,只能在正常启动时通过 VPN 访问。出于同样的原因,从 Live CD 或 USB 记忆棒启动也是不切实际的。

系统是 Ubuntu 16.04(超出 EOL,不要问),但问题和答案可能更通用。

答案1

描述的程序这里(它本身可能是一个不完美的副本这个询问 Ubuntu 答案)创造了奇迹。我把它复制到这里,并添加一些更多的解释。

程序

  1. 打开两个到目标服务器的 SSH 会话。

  2. 在第一个会话中,通过运行以下命令获取 bash 的 PID:

     echo $$
    
  3. 在第二个会话中,使用以下命令启动身份验证代理:

     pkttyagent --process 29824
    

    使用从步骤 1 获得的 pid。

  4. 回到第一个会话,运行:

     pkexec chown root:root /etc/sudoers /etc/sudoers.d -R
    
  5. 在第二个会话密码提示中输入密码。

解释

与 类似sudopkexec允许授权用户以另一个用户的身份执行程序,通常为root。它使用 polkit 进行身份验证;特别org.freedesktop.policykit.exec是使用了该动作。

此操作定义于/usr/share/polkit-1/actions/org.freedesktop.policykit.policy

  <action id="org.freedesktop.policykit.exec">
    <description>Run programs as another user</description>
    <message>Authentication is required to run a program as another user</message>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>auth_admin</allow_active>
    </defaults>
  </action>

auth_admin表示允许管理用户执行此操作。谁有资格成为管理用户?

在这个特定的系统(Ubuntu 16.04)上,配置如下 /etc/polkit-1/localauthority.conf.d/51-ubuntu-admin.conf

[Configuration]
AdminIdentities=unix-group:sudo;unix-group:admin

因此组中的任何用户sudoadmin都可以使用pkexec

在较新的系统(Arch Linux)上,它位于/usr/share/polkit-1/rules.d/50-default.rules

polkit.addAdminRule(function(action, subject) {
    return ["unix-group:wheel"];
});

所以在这里,wheel组中的每个人都是管理用户。

pkexec手册页中,它指出如果当前会话没有找到身份验证代理,则pkexec使用其自己的文本身份验证代理,该代理似乎是pkttyagent.事实上,如果您pkexec在没有首先启动该pkttyagent进程的情况下运行,系统会在同一 shell 中提示您输入密码,但输入密码后会失败:

polkit-agent-helper-1: error response to PolicyKit daemon: GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed: No session for cookie

这似乎是polkit 中的一个老 bug这似乎没有得到任何牵引力。更多的讨论

使用两个 shell 的技巧是只是一个解决方法对于这个问题。

答案2

启动到实时环境并从那里修复它。

这显然需要“物理等效”访问的物理访问(如果处理 VM 或 VPS),但它几乎总是有效,不关心您拥有什么 init 系统,也不关心您是否拥有root 密码。

一般的做法比较简单:

  1. 准备与您正在使用的操作系统兼容的 Live CD(或其他启动介质)(大多数情况下,这只是为了支持挂载根文件系统所需的存储驱动程序和文件系统的特定组合)。
  2. 使用该启动介质启动受影响的系统。
  3. 将受影响系统的根文件系统挂载到某处。
  4. 编辑并保存文件。
  5. 重启。

这种修复之所以有效,是因为它完全避开了受影响系统的访问控制,让您几乎可以做任何您想做的事情。这种对系统的不受限制的访问级别是物理安全如此重要的部分原因。

请注意,如果采用这种方法,您可能需要在重新启动回到“正常”系统时执行一些特殊操作才能正常工作。在原生 Ubuntu 安装上不需要这样做,但如果您使用 SELinux(甚至不太可能使用 IMA 和 EVM),您可能需要添加额外的引导选项,然后从引导的系统运行命令来修复安全标签。


对于那些有root密码,只需使用单用户模式。

Systemd 将此称为“救援模式”,但其他人都将其称为单用户模式。这实际上会启动到 root shell,除了运行关键服务之外几乎什么都没有。它传统上用于固定确切地这类问题。

这样做的一个缺点是,在任何适当保护的现代系统上,单用户模式都受到密码保护,并且需要能够以 root 用户身份登录(原因是访问系统控制台并不意味着物理访问)到系统硬件,因此应该使用一些身份验证)。

答案3

每当您计划尝试sudo配置时,最好保持另一个根终端打开:以防万一您破坏了某些内容,您已经有权修复它。

如果无法保持终端打开(例如,您的实验涉及重新启动),请为用户设置实际密码root。然后,如果sudo损坏,您可以简单地登录root(打开新控制台或运行su)并修复您的系统。

相关内容