前言
这是一个相当复杂的问题,与 sudoers 文件和 sudo 命令有关。
注意:我在一台运行 Ubuntu Desktop 13.04 的专用机器上进行了这些更改,我纯粹将其用于学习目的。我知道启用 NOPASSWD sudo 会带来巨大的安全风险。
问题
最初,我对 sudoers 文件 ( /etc/sudoers
) 的唯一更改是一行,即用户规范,该规范应使 nicholsonjf 能够使用 sudo 运行所有命令而无需输入密码(请参阅以 nicholsonjf 开头的行):
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# Host alias specification
# User alias specification
# Cmnd alias specification
# User privilege specification
root ALL=(ALL:ALL) ALL
nicholsonjf ALL=NOPASSWD: ALL
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL
# See sudoers(5) for more information on "#include" directives:
#includedir /etc/sudoers.d
但是这不起作用,每次我以 nicholsonjf 身份运行命令时,系统仍会提示我输入密码。只有将 nicholsonjf 从 sudo 和 admin 组中删除后,我才能开始以 nicholsonjf 身份运行 sudo 命令。
有人能解释一下为什么这有效吗?
是不是因为用户 nicholsonjf 从admin
和两个组规范sudo
(见下面的 sudoers 文件)继承了 sudo 权限,而由于它们在配置文件中位置更靠下,所以它们覆盖了 nicholsonjf 用户规范?
答案1
您添加的行已被覆盖。来自man sudoers
:
当多个条目与用户匹配时,将按顺序应用它们。如果有多个匹配项,则使用最后一个匹配项(不一定是最具体的匹配项)。
就你的情况而言,nicholsonjf
你是这个团体的成员sudo
,因此对他来说,这句话适用:
%sudo ALL=(ALL:ALL) ALL
如果您想要覆盖条目,/etc/sudoers
只需将新条目放在它们后面。
新条目应如下所示
myuser ALL=(ALL) NOPASSWD: ALL
对于单个用户,或
%sudo ALL=(ALL) NOPASSWD: ALL
对于一个群体。
答案2
sudoers
对于单个用户,使用以下命令在文件末尾添加此行sudo visudo
:
superuser ALL=(ALL) NOPASSWD:ALL
对于团体
%supergroup ALL=(ALL) NOPASSWD:ALL
答案3
运行此命令,当当前用户使用以下命令时,永远不会提示该用户输入密码sudo
:
echo "$USER ALL=(ALL:ALL) NOPASSWD: ALL" | sudo tee "/etc/sudoers.d/dont-prompt-$USER-for-sudo-password"
它创建一个名为的文件,/etc/sudoers.d/dont-prompt-<YOUR USERNAME>-for-sudo-password
其内容如下:
<YOUR USERNAME> ALL=(ALL:ALL) NOPASSWD: ALL
这是因为 Debian 和 Ubuntu 的默认/etc/sudoers
文件有这一行
#includedir /etc/sudoers.d
这使得它处理/etc/sudoers.d/
目录中的文件。如果上述命令不起作用,请检查是否没有人从/etc/sudoers
文件中删除了该行。
答案4
当我研究这个问题时,我意识到/etc/sudoers
文件中有一行不是注释,而是指示这使得目录下的任何文件或文件/etc/sudoers/*
夹覆盖的内容/etc/sudoers
。
这是一个很狡猾的小指令,因为乍一看它似乎是一行注释。它看起来像这样:
#includedir /etc/sudoers.d
这是我在临时 Docker 映像中实现非 root、无密码用户的方法,该映像用于以 ubuntu:18.04 为基础的 CICD 管道:
RUN \
useradd -U foo -m -s /bin/bash -p foo -G sudo && passwd -d foo && passwd -d root && \
sed -i /etc/sudoers -re 's/^%sudo.*/%sudo ALL=(ALL:ALL) NOPASSWD: ALL/g' && \
sed -i /etc/sudoers -re 's/^root.*/root ALL=(ALL:ALL) NOPASSWD: ALL/g' && \
sed -i /etc/sudoers -re 's/^#includedir.*/## Removed the #include directive! ##"/g' && \
echo "Customized the sudoers file for passwordless access!" && \
echo "foo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
echo "root ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
echo "foo user:"; su foo -c 'whoami && id' && \
echo "root user:"; su root -c 'whoami && id'
上述代码会发生什么情况:
- 用户和组
foo
已创建。 - 该用户
foo
被添加到foo
和sudo
组中。 - 主目录设置为
/home/foo
。 - 外壳设置为
/bin/bash
。 - 该
sed
命令对文件进行内联更新,/etc/sudoers
以允许foo
用户root
无密码访问该sudo
组。 - 该
sed
命令禁用#includedir
允许子目录中的任何文件覆盖这些内联更新的指令。