My question is: why should I have all those commands listed? Once I have forbidden execution of /usr/bin/apt with !/usr/bin/apt haven’t I also implicitly restricted both /usr/bin/apt upgrade and /usr/bin/apt install?
In the man page for the sudoers file in the section ‘SECURITY NOTES’ you’ll find a subsection named “Limitations of the ‘!’ operator”. Basically it’s at best advisory since users who are allowed to copy or move any file or can run a shell with elevated privileges can easily circumvent the prohibition.
Rather than restricting admins, would it make better sense to use non-admin users (i.e., not part of the sudo group), and instead grant them a specific set of commands?
Create a new group; let’s call it webadmin. Then, allow that group access to a specific set of commands. E.g. create a new file /etc/sudoers.d/webadmin (using visudo):
That allows users belonging to the group webadmin to execute systemctl restart nginx and whatever else you specify, but not to use any other sudo commands.
Important caveats:
I haven’t tested this, so please test carefully before taking it live.
Some commands (e.g. less) allow the user to drop into a root shell, where they can do anything. Check that you allow only commands that don’t allow the user to drop into a root shell. Likewise, as @hdd-gehrke warned, don’t allow commands that manipulate files (including editing), because then they can create, delete and change the sudoers files, granting themselves sudo access.
I’ve never come across such a list — I imagine that there are far too many Linux commands! It would be impossible to be comprehensive. Plus, each distribution and each organisation or individual could have installed or modified extra items.
I would check each and every command on a case-by-case basis. Also, it would be vital to use commands that a user cannot change. For example, including a command in the user’s home folder would be suicide; it must be in a folder that only root can modify. Hence the need to include a path, and not rely on ${PATH}.
If users are allowed to run less as root (sudo less), than a simple ‘!bash’ in less gives them a root shell (!COMMAND will run a command from less). This is almost the same command as in vi (:!COMMAND in vi). nano allows executing non-interactive commands using ctrl-T with the output going into the editor buffer, so you can’t get a root shell directly but you can call a terminal (e.g. xterm) or a terminal multiplexer (e.g. tmux) and get a root shell that way. All programs that allow the user to call another program can be used that way. In some cases there are restricted versions of programs which disallow calling external programs (e.g. rvim is a restricted version of vim which can’t call external programs). So if you want to allow users to run an editor as root but not to give them a root shell that could be an option. Or you could allow them to use sudoedit or sudo -e, which will make a temporary copy of a file call an editor without root privileges on that copy and will copy the temporary file back to the original after editing.
So @paddylandau’s advice of only giving users the commands they need to do their job is really good. Using groups to define roles and then assigning users to those groups is AFAIK considered the right way to handle things.
Yes, you can. sudo matches the command with options as strings against sudoers. Even reversing options order will already cause failure to match thesudoers definition.
OK, I probably misunderstood it. I read it in the context of disallowing this command. If you allow a command with arguments, then you can only execute the exact command with the exact arguments.
I’ve just tested this for you. The answer is that the user can only use that exact command; any deviation is forbidden.
alice@u2604clevisvm:~$ sudo true
sudo: I'm sorry alice. I'm afraid I can't do that
alice@u2604clevisvm:~$ sudo ls
sudo: I'm sorry alice. I'm afraid I can't do that
alice@u2604clevisvm:~$ sudo ls -la
sudo: I'm sorry alice. I'm afraid I can't do that
alice@u2604clevisvm:~$ sudo ls -laF
sudo: I'm sorry alice. I'm afraid I can't do that
alice@u2604clevisvm:~$ sudo ls -aFl
sudo: I'm sorry alice. I'm afraid I can't do that
alice@u2604clevisvm:~$ sudo ls -alF snap
sudo: I'm sorry alice. I'm afraid I can't do that
alice@u2604clevisvm:~$ sudo ls -alF
[sudo: authenticate] Password:
total 96
drwxr-x--- 14 alice alice 4096 Aug 16 15:08 ./
drwxr-xr-x 4 root root 4096 Aug 16 15:05 ../
-rw-r--r-- 1 alice alice 220 Aug 16 15:05 .bash_logout
-rw-r--r-- 1 alice alice 3771 Aug 16 15:05 .bashrc
drwx------ 13 alice alice 4096 Aug 16 15:08 .cache/
drwx------ 13 alice alice 4096 Aug 16 15:08 .config/
drwx------ 4 alice alice 4096 Aug 16 15:08 .local/
-rw-r--r-- 1 alice alice 807 Aug 16 15:05 .profile
drwxr-xr-x 2 alice alice 4096 Aug 16 15:08 Desktop/
drwxr-xr-x 2 alice alice 4096 Aug 16 15:08 Documents/
drwxr-xr-x 2 alice alice 4096 Aug 16 15:08 Downloads/
drwxr-xr-x 2 alice alice 4096 Aug 16 15:08 Music/
drwxr-xr-x 2 alice alice 4096 Aug 16 15:08 Pictures/
drwxr-xr-x 2 alice alice 4096 Aug 16 15:08 Public/
drwxr-xr-x 2 alice alice 4096 Aug 16 15:08 Templates/
drwxr-xr-x 2 alice alice 4096 Aug 16 15:08 Videos/
drwx------ 5 alice alice 4096 Aug 16 15:08 snap/
alice@u2604clevisvm:~$
In other words, if you supply arguments, sudoers takes the most conservative interpretation. But, if you don’t supply arguments, the user can add any arguments as they choose.
If generically, then no, because that allows editing any file as root, including sudoers itself. However, it’s possible to allow only a selected file, e.g. let the user edit only two specific files with sudoedit as follows.
alice ALL=(root) /usr/bin/sudoedit /etc/fstab, /usr/bin/sudoedit /usr/share/motd
So, sudoedit is an excellent idea if an editor is required.