Only the Most Trivial or Most Expansive Sudoer Privileges are Easy to Grant
When working with Linux systems there are many circumstances under which it is convenient to grant users limited sudoer rights, so as to permit execution of specific commands as another user, usually root
. This is easy to accomplish for prepackaged scripts. For example, a deploy
user might have the following placed in /etc/sudoers.d/deploy
:
# The deploy user can execute the run-deployment script as root, # but not as any other user, without needing to enter a password. deploy ALL = NOPASSWD: /usr/bin/run-deployment
It is also easy to grant sweeping sudoer rights, the ability to execute anything as any user. This level of access is typically given to, for example, stateless server administrators, who log in with their own accounts but are expected to exercise full control over a server:
# Anyone in the admin group can execute any commmand as any user. %admin ALL = (ALL) NOPASSWD: ALL
The challenges start when, for whatever reason, you want to grant the ability to run commands with arbitrary arguments. Sudo is a very intricate piece of software, with a complex configuration space, and its interaction with permissions, bash scripts, and other aspects of a Linux OS are beset with subtle pitfalls at the best of times. Let us say, to pick a contrived example, that you want usera
to be able to edit files under /home/userb/export
as userb
. You might try something like this:
# usera can edit the contents of the export directory as userb. usera ALL = (userb) NOPASSWD: /bin/nano /home/userb/export/*
Unfortunately, that glob wildcard allows all sorts of bad behavior, such as the following:
nano /home/userb/export/../.ssh/authorized_keys nano /home/userb/export/innocuous /home/userb/.ssh/id_rsa
This is one of the more obvious of a large number of possible problems that can arise in the course of balancing freedom to enter arbitrary parameters with the need to set boundaries to access for sudoers. Safely providing constrained but still fairly free access within those constraints requires both a good understanding of the intricacies of sudo configuration, and usually also the time to write additional scripts to process options. Glob matching in sudo strings is fairly limited in the grand scheme of things, but it is possible to shut off some undesirable options such as directory traversal as follows:
# usera can edit the contents of the export directory as userb. usera ALL = (userb) NOPASSWD: /bin/nano /home/userb/export/* # But no directory traversal. usera ALL = (userb) NOPASSWD: !/bin/nano /home/userb/export/*..* # And no extra parameters. usera ALL = (userb) NOPASSWD: !/bin/nano /home/userb/export/* *
Not every hole is so easily closed, however, and thus the best option in most situations involving wildcards is something like this, where an intermediary script is used:
# usera can edit the contents of the export directory as userb. usera ALL = (userb) NOPASSWD: /usr/bin/local/edit-userb-export *
Write the edit-userb-export
bash script, or a script in some other language, to vet the parameters it receives to ensure they are in fact paths to files in the /home/userb/export
directory. Trivially, that might be something like the following:
#!/bin/bash ABS_PATH=$(readlink -f "${1}") if [[ "${ABS_PATH}" =~ ^/home/userb/export/[^[:space:]]*$ ]]; then nano "${ABS_PATH}" else exit 1 fi
Is this worth the time and effort, however? In doing this you have only pushed the security question a little further down the line, and taken on yourself the task of carefully examining and correctly solving a permissions issue. This is usually not the right approach to any problem, as the odds of creating a bulletproof solution for even simple cases are not all that high, even given a bunch of smart people in the room. We can see the evidence for that all around us, in the number of security holes found even in software created by good, experienced teams. If you find yourself having to set up complicated sudoer rules and the attendant supporting scripts, it is usually a sign that a different approach to the higher level problem is required.