在没有密码的情况下授予 sudo 访问权限后,sudoers 中出现解析错误

在没有密码的情况下授予 sudo 访问权限后,sudoers 中出现解析错误

我正在为 Linux 制作一个桌面应用程序,该应用程序与一些 Ubuntu 系统文件交互。因此,在最终用户安装我的软件时,我需要生成一个文件,让/etc/sudoers.d/一些脚本无需知道密码即可访问系统文件。用户将在安装过程中输入密码,但之后他们不必输入密码。在安装过程中,他们将运行give-sudo.sh包含以下几行 Bash 代码的脚本:

echo '$USER ALL=(ALL) NOPASSWD: power_off.sh' >> /etc/sudoers.d/moss-priv
echo '$USER ALL=(ALL) NOPASSWD: reboot.sh' >> /etc/sudoers.d/moss-priv
echo '$USER ALL=(ALL) NOPASSWD: timeout_moss.sh' >> /etc/sudoers.d/moss-priv
echo '$USER ALL=(ALL) NOPASSWD: timeout_default.sh' >> /etc/sudoers.d/moss-priv
echo '$USER ALL=(ALL) NOPASSWD: set_next_os.sh' >> /etc/sudoers.d/moss-priv
echo '$USER ALL=(ALL) NOPASSWD: boot_os_1.sh' >> /etc/sudoers.d/moss-priv
echo '$USER ALL=(ALL) NOPASSWD: boot_os_2.sh' >> /etc/sudoers.d/moss-priv
echo '$USER ALL=(ALL) NOPASSWD: give_sudo.sh' >> /etc/sudoers.d/moss-priv

它应该创建一个名为的文件moss-priv,并附加使我的脚本无需密码即可运行所需的行。我有 8 个脚本,所以我附加了 8 行代码。命令echo运行正常,moss-priv生成并显示其内容:

$USER ALL=(ALL) NOPASSWD: power_off.sh
$USER ALL=(ALL) NOPASSWD: reboot.sh
$USER ALL=(ALL) NOPASSWD: timeout_moss.sh
$USER ALL=(ALL) NOPASSWD: timeout_default.sh
$USER ALL=(ALL) NOPASSWD: set_next_os.sh
$USER ALL=(ALL) NOPASSWD: boot_os_1.sh
$USER ALL=(ALL) NOPASSWD: boot_os_2.sh
$USER ALL=(ALL) NOPASSWD: give_sudo.sh

问题就出在此时。脚本无需输入密码sudo,而是打印堆栈跟踪,指出每行(1-8)都发生了错误。不仅如此,如果我sudo出于任何原因尝试调用,它会显示“授权失败”和堆栈跟踪。因此,我完全失去了sudo访问权限,甚至无法回去删除导致此问题的文件。我最终不得不重新安装整个操作系统才能使其恢复正常。

现在我已经sudo回来了,我准备在弄清楚文件出了什么问题后再试一次moss-priv。虽然我搞不清楚,但我觉得它看起来不错。帮忙?

我很高兴能找到这个问题的解决方案或好的替代方法。


错误:

\>>> /etc/sudoers.d/moss-priv: syntax error near line 1 <<<
\>>> /etc/sudoers.d/moss-priv: syntax error near line 2 <<<
\>>> /etc/sudoers.d/moss-priv: syntax error near line 3 <<<
\>>> /etc/sudoers.d/moss-priv: syntax error near line 4 <<<
\>>> /etc/sudoers.d/moss-priv: syntax error near line 5 <<<
\>>> /etc/sudoers.d/moss-priv: syntax error near line 6 <<<
\>>> /etc/sudoers.d/moss-priv: syntax error near line 7 <<<
\>>> /etc/sudoers.d/moss-priv: syntax error near line 8 <<<
\sudo: parse error in /etc/sudoers.d/moss-priv near line 1
\sudo: no valid sudoers sources found, quitting
\sudo: unable to initialize policy plugin1\\

更新:根据建议的修复,我有一个文件give_sudo.sh

echo "$SUDO_USER ALL=(ALL) NOPASSWD: /home/jeremiahdgage/Desktop/MOSS/power_off.sh" >> /etc/sudoers.d/moss-priv echo "$SUDO_USER ALL=(ALL) NOPASSWD: /home/jeremiahdgage/Desktop/MOSS/reboot.sh" >> /etc/sudoers.d/moss-priv echo "$SUDO_USER ALL=(ALL) NOPASSWD: /home/jeremiahdgage/Desktop/MOSS/timeout_moss.sh" >> /etc/sudoers.d/moss-priv echo "$SUDO_USER ALL=(ALL) NOPASSWD: /home/jeremiahdgage/Desktop/MOSS/timeout_default.sh" >> /etc/sudoers.d/moss-priv echo "$SUDO_USER ALL=(ALL) NOPASSWD: /home/jeremiahdgage/Desktop/MOSS/set_next_os.sh" >> /etc/sudoers.d/moss-priv echo "$SUDO_USER ALL=(ALL) NOPASSWD: /home/jeremiahdgage/Desktop/MOSS/boot_os_1.sh" >> /etc/sudoers.d/moss-priv echo "$SUDO_USER ALL=(ALL) NOPASSWD: /home/jeremiahdgage/Desktop/MOSS/boot_os_2.sh" >> /etc/sudoers.d/moss-priv echo "$SUDO_USER ALL=(ALL) NOPASSWD: /home/jeremiahdgage/Desktop/MOSS/give_sudo" >> /etc/sudoers.d/moss-priv

其中一个脚本是这样的timeout_moss.sh

sudo sed -i 's/GRUB_HIDDEN_TIMEOUT=10/GRUB_HIDDEN_TIMEOUT=0.01/g' /etc/default/grub

当我运行它时,bash timeout_moss.sh(当我在当前目录中时)它仍然要求我输入密码...为什么?

答案1

echo '$USER ALL=(ALL) NOPASSWD: power_off.sh' >> /etc/sudoers.d/moss-priv

此后,文件看起来不太好。您需要提供完全限定文件名(下面我假设/sbin/power_off.sh)。此外,$USER单引号中的 不会展开,它会以文字形式进入文件$USER;我猜测这不是你想要的。使用双引号并指定满的小路:

echo "$USER ALL=(ALL) NOPASSWD: /sbin/power_off.sh" >> /etc/sudoers.d/moss-priv

文件中的行将如下所示:

kamil ALL=(ALL) NOPASSWD: /sbin/power_off.sh

提示:

  • 如果不可执行,则此操作将不起作用/sbin/power_off.sh。使用 使其可执行chmod
  • 确保$USER按预期展开。如果您的安装脚本运行sudo后,您可能需要$SUDO_USER(请参阅man 8 sudo)。无论如何,建议在写入文件之前检查扩展值是否合理。
  • 使用这里的文件(不带引号单词因为您想要$SUDO_USER扩展)以更优雅的方式写入文件。此示例将重新创建文件:

    cat >/etc/sudoers.d/moss-priv <<EOF
    $SUDO_USER ALL=(ALL) NOPASSWD: /sbin/power_off.sh
    $SUDO_USER ALL=(ALL) NOPASSWD: /sbin/reboot.sh
    $SUDO_USER ALL=(ALL) NOPASSWD: /sbin/timeout_moss.sh
    $SUDO_USER ALL=(ALL) NOPASSWD: /sbin/timeout_default.sh
    $SUDO_USER ALL=(ALL) NOPASSWD: /sbin/set_next_os.sh
    $SUDO_USER ALL=(ALL) NOPASSWD: /sbin/boot_os_1.sh
    $SUDO_USER ALL=(ALL) NOPASSWD: /sbin/boot_os_2.sh
    $SUDO_USER ALL=(ALL) NOPASSWD: /sbin/give_sudo.sh
    EOF
    
  • 注意sudoers允许您指定整个目录(通过其完整路径,它应该以 开头/并以 结尾/)。将脚本移动到专用目录,您只需在 中添加一行即可/etc/sudoers.d/moss-priv。但是,如果您需要通过 访问您的工具PATH,请记住sudo可以使用单独的PATH
  • 在您的测试中,首先打开一个提升的shell(例如sudo su -)并一直保持打开状态。在常规 shell 中测试sudo更改后是否有效。如果您失去sudo访问权限,请使用提升的 shell 来解决问题(在您的情况下,删除/etc/sudoers.d/moss-priv应该可以)。
  • 如果远程工作,请在测试中使用tmuxscreen作为普通用户,并从那里打开提升的 shell。这样,即使您在要修复访问sudo权限的最关键时刻暂时失去连接,shell 仍会存活。您将能够跳转到提升的 shell,而无需sudo重新连接到tmux/ screen

答案2

尝试使用双引号:

echo "$USER ALL=(ALL) NOPASSWD: power_off.sh" >> /etc/sudoers.d/moss-priv

因此该$USER变量将被其内容替换。单引号可防止变量被解释。

相关内容