On a Debian 8 system managed by Chef, I encountered an odd situation where some commands in /etc/sudoers.d
worked perfectly while others failed with permission errors. For example:
# Working configuration
user ALL=(root) NOPASSWD:/usr/sbin/nginx
# Failing configuration
user ALL=(root) NOPASSWD:/usr/sbin/update-rc.d
The error message showed:
Sorry, user user is not allowed to execute '/usr/sbin/update-rc.d' as root on server.
Checking the sudo version revealed:
Sudo version 1.8.10p3
Sudoers policy plugin version 1.8.10p3
Sudoers file grammar version 43
The syslog showed:
Mar 5 12:12:51 server sudo: user : command not allowed ; TTY=pts/0 ; PWD=/home/user ; USER=root ; COMMAND=/usr/sbin/update-rc.d
Several factors could cause this behavior:
# 1. File permissions in /etc/sudoers.d
ls -l /etc/sudoers.d/
# 2. Syntax errors in sudoers files
visudo -c -f /etc/sudoers.d/update-rc.d
# 3. SELinux or AppArmor restrictions
getenforce
aa-status
After thorough testing, the issue stemmed from how sudo resolves command paths. The working command (nginx
) was a direct symlink:
ls -l /usr/sbin/nginx
lrwxrwxrwx 1 root root 22 May 15 2015 /usr/sbin/nginx -> /etc/alternatives/nginx
While the failing command (update-rc.d
) was a Perl script:
file /usr/sbin/update-rc.d
/usr/sbin/update-rc.d: Perl script text executable
The fix required modifying the sudoers entry to explicitly specify the interpreter:
# Original (failing)
user ALL=(root) NOPASSWD:/usr/sbin/update-rc.d
# Fixed version
user ALL=(root) NOPASSWD:/usr/bin/perl /usr/sbin/update-rc.d
Alternatively, for better security:
user ALL=(root) NOPASSWD:/usr/sbin/update-rc.d *
After making changes:
# 1. Check syntax
visudo -c
# 2. Test execution
sudo -u user sudo -l
# 3. Verify command execution
sudo -u user sudo /usr/sbin/update-rc.d
For Chef-managed systems, the recipe should include:
template '/etc/sudoers.d/update-rc.d' do
source 'sudoers_update-rc.d.erb'
mode '0440'
owner 'root'
group 'root'
variables(
user: 'user'
)
verify 'visudo -c -f %{path}'
end
And the template (sudoers_update-rc.d.erb
):
<%= @user %> ALL=(root) NOPASSWD:/usr/bin/perl /usr/sbin/update-rc.d *
On a Debian 8 system managed by Chef, we're seeing inconsistent behavior with sudo
permissions. While some commands work perfectly through sudo (like /usr/sbin/nginx
), others (like /usr/sbin/update-rc.d
) fail with permission errors despite identical configuration in /etc/sudoers.d/
.
user@www42:~$ sudo update-rc.d
[sudo] password for user:
Sorry, user user is not allowed to execute '/usr/sbin/update-rc.d' as root on server.
Both sudoers files appear correctly formatted:
# Working configuration
root@server:~# cat /etc/sudoers.d/nginx
user ALL=(root) NOPASSWD:/usr/sbin/nginx
# Failing configuration
root@server:~# cat /etc/sudoers.d/update-rc.d
user ALL=(root) NOPASSWD:/usr/sbin/update-rc.d
Several potential issues could cause this behavior:
- Path Resolution: The actual command being executed might differ from what's specified
- Permission Masking: A more restrictive rule elsewhere in sudoers
- Symbolic Links: The command might be a symlink to another path
- SELinux/AppArmor: Additional security layers blocking execution
First, verify the actual path of the failing command:
which update-rc.d
readlink -f $(which update-rc.d)
Check for conflicting sudoers rules:
sudo visudo -c
sudo grep -r "update-rc.d" /etc/sudoers*
Inspect system logs for more details:
journalctl -xe
grep sudo /var/log/auth.log
If the command is a symlink:
# Instead of
user ALL=(root) NOPASSWD:/usr/sbin/update-rc.d
# Use the actual path
user ALL=(root) NOPASSWD:/bin/update-rc.d
For permission masking issues, add more specific rules:
# Give explicit permission first
user ALL=(root) NOPASSWD:/usr/sbin/update-rc.d
# Then restrict other permissions
user ALL=(root) NOPASSWD:!/bin/*, !/usr/bin/*
For SELinux/AppArmor issues:
# Check SELinux context
ls -Z /usr/sbin/update-rc.d
# Temporarily set permissive mode
setenforce 0
sudo update-rc.d
setenforce 1
Run sudo in debug mode:
sudo -l -U user
sudoedit -l -U user
Check command path resolution:
strace -f -e execve sudo update-rc.d 2>&1 | grep execve
Examine PAM configuration:
cat /etc/pam.d/sudo