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

Tho*_*mas 33 linux sudo

我收到以下错误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
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

Tho*_*mas 59

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

程序

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

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

     echo $$
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在第二个会话中,使用以下命令启动身份验证代理:

     pkttyagent --process 29824
    
    Run Code Online (Sandbox Code Playgroud)

    使用从步骤 1 获得的 pid。

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

     pkexec chown root:root /etc/sudoers /etc/sudoers.d -R
    
    Run Code Online (Sandbox Code Playgroud)
  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>
Run Code Online (Sandbox Code Playgroud)

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

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

[Configuration]
AdminIdentities=unix-group:sudo;unix-group:admin
Run Code Online (Sandbox Code Playgroud)

因此组中的任何用户sudo或都admin可以使用pkexec

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

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

所以在这里,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
Run Code Online (Sandbox Code Playgroud)

这似乎是polkit 中的一个老错误,似乎没有得到任何关注。更多讨论

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


Aus*_*arn 6

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

\n

这显然需要物理访问\xe2\x80\x98物理等效\xe2\x80\x99访问(如果处理VM或VPS),但它几乎总是有效,不关心\xe2\x80\x99什么初始化系统你有,并且不关心你是否有 root 密码。

\n

一般的做法比较简单:

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

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

\n

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

\n
\n

对于那些这样做的人root 密码的人,只需使用单用户模式即可。

\n

Systemd 将此称为 \xe2\x80\x98rescue 模式\xe2\x80\x99,但其他人都将其称为单用户模式。这实际上会启动到 root shell,除了运行关键服务之外几乎什么都没有。它\xe2\x80\x99s传统上用于精确修复此类问题。

\n

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

\n

  • 如果您有 root 密码,则不需要单用户模式;只需使用“su”即可。 (4认同)