Preface
This is a fairly complex question related to the sudoers file and the sudo command in general.
NOTE: I have made these changes on a dedicated machine running Ubuntu Desktop 13.04, that I use purely for learning purposes. I understand it's a huge security risk to enable NOPASSWD sudo.
Question
Initially, my only change to the sudoers file (/etc/sudoers) was one line, a user specification that should have enabled nicholsonjf to run all commands with sudo without having to enter a password (see the line that starts with 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.dHowever this did not work, and I was still prompted for my password every time I ran a command as nicholsonjf. I was only able to start running sudo commands as nicholsonjf once I removed nicholsonjf from the sudo and admin groups.
Can anyone explain why this worked?
Is it because the user nicholsonjf was inheriting sudo rights from the two group specifications of admin and sudo (seen below in the sudoers file), which were overriding the nicholsonjf user specification because they were further down in the config file?
6 Answers
The line you added was overridden. From man sudoers:
When multiple entries match for a user, they are applied in order. Where there are multiple matches, the last match is used (which is not necessarily the most specific match).
In your case nicholsonjf was a member of the group sudo so for him this line applied:
%sudo ALL=(ALL:ALL) ALLIf you want to override entries in /etc/sudoers just put the new entries after them.
The new entry should look like
myuser ALL=(ALL) NOPASSWD: ALL for a single user, or
%sudo ALL=(ALL) NOPASSWD: ALL for a group.
For a single user, add this line at the end of your sudoers file using the sudo visudo command:
superuser ALL=(ALL) NOPASSWD:ALLFor a group
%supergroup ALL=(ALL) NOPASSWD:ALL 2 Run this command to never prompt the current user for a password when that user uses sudo:
echo "$USER ALL=(ALL:ALL) NOPASSWD: ALL" | sudo tee "/etc/sudoers.d/dont-prompt-$USER-for-sudo-password"It creates a file called /etc/sudoers.d/dont-prompt-<YOUR USERNAME>-for-sudo-password with the following contents:
<YOUR USERNAME> ALL=(ALL:ALL) NOPASSWD: ALLThis works because Debian's and Ubuntu's default /etc/sudoers file has this line
#includedir /etc/sudoers.dwhich makes it process files in /etc/sudoers.d. If the command above didn't work, check that no one has removed that line from your /etc/sudoers.
As Vince has mentioned in a comment, you can use this line:
%sudo ALL=NOPASSWD: ALL(This is different from the lines shown in those answers, and it solved the problem for me.)
5As I was researching this, I realized that there's a line in the /etc/sudoers file that is not a comment, but a directive that makes any file or folder under the directory /etc/sudoers/* override the contents of /etc/sudoers.
This is a sneaky little directive, as it appears to be a commented line upon first glance. It looks like this:
#includedir /etc/sudoers.dThis is how I've implemented the non-root, passwordless user in an ephemeral Docker Image for use in a CICD pipeline with the base image of ubuntu:18.04:
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'What happens with the above code:
- The user and group
foois created. - The user
foois added to the both thefooandsudogroup. - The home directory is set to
/home/foo. - The shell is set to
/bin/bash. - The
sedcommand does inline updates to the/etc/sudoersfile to allowfooandrootusers passwordless access to thesudogroup. - The
sedcommand disables the#includedirdirective that would allow any files in subdirectories to override these inline updates.
One can insert a string in one line without EOF formatting at end of sudoers file or remove with sed -i:
cat >> /etc/sudoers <<<'PaSe ALL=(ALL:ALL) NOPASSWD:ALL'
Reference: