Troubleshooting Sudo Permission Issues on Debian: Why Certain Commands Fail in /etc/sudoers.d


7 views

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:

  1. Path Resolution: The actual command being executed might differ from what's specified
  2. Permission Masking: A more restrictive rule elsewhere in sudoers
  3. Symbolic Links: The command might be a symlink to another path
  4. 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