Add a Least-Privilege sudoers Rule and Prove It Works
Someone needs to run one command as root, and ALL=(ALL) ALL in sudoers is not the answer. You will write one rule that lets a named user run one exact command as one target account, then check it is both valid and effective. Allow about fifteen minutes.
The route
Jump straight to the step you need, or tick off Done means at the end.
- Checked against: sudo 1.9.15p5 on Ubuntu.
- You need: an existing administrative login and a command that is safe to test.
- Test command:
/usr/bin/systemctl status ssh, because it reads service state without starting, stopping or reloading anything. Replace it only with a command whose arguments and effects you have checked.
Warning
Sudo policy is security-sensitive. A typo can grant too much access, and a syntax error can stop sudo loading its policy at all. Keep a root shell or console session open the whole time and do not close it until the new rule has been tested.
1. Record the installed sudo version
Confirm the binary and policy plugin you are about to rely on. Ordinary, read-only:
$ sudo -V | sed -n '1,5p'
Sudo version 1.9.15p5
Sudoers policy plugin version 1.9.15p5
Sudoers file grammar version 50
Package revision and plugin details may differ on another host. What matters is that you are writing for the sudoers format this version provides, not pasting a rule from an unrelated system.
Checkpoint
Your administrative session is still open, and the version is written down before you change policy.
2. Choose an exact command and target
A sudoers user specification makes four decisions:
- Who may run the command.
- On which host.
- As which target user.
- Which command, with which arguments.
Keep ALL out of it while you learn the shape: in the command position, ALL permits any command. Here the placeholder account is deploy, the host is any host, the target is root and the command is the read-only service query:
deploy ALL = (root) /usr/bin/systemctl status ssh
The path is fully qualified, and status ssh is part of the match, so a request for another unit or another systemctl subcommand does not match. Check the real path on your system:
$ command -v systemctl
/usr/bin/systemctl
$ systemctl status ssh --no-pager
host-specific service status is printed here
Warning
A command that accepts a shell, an editor, a scripting language or an option that runs another program is not a narrow capability. It can be an indirect route to a root shell even when its path looks specific.
3. Create a separate rule file
On Ubuntu, local rules belong in /etc/sudoers.d, not appended to the main file. The installed configuration reads that directory with @includedir, and there is a catch in how:
- Skipped: files ending in
~or containing a dot.50-deploy.confwould be ignored. - Read order: the remaining files, in lexical order.
- So: use a simple, consistently numbered name with no dot.
This needs elevated privileges. visudo locks the policy while you edit and checks the result before installing it:
$ sudo visudo -f /etc/sudoers.d/50-deploy-systemctl
Enter exactly this rule, changing only the account, target and command after checking them:
deploy ALL = (root) /usr/bin/systemctl status ssh
Save and exit. Success normally drops you back at the shell with no error. If visudo reports a syntax problem, choose the option to return to editing and fix it.
Warning
Never force installation of a file that visudo says is invalid.
Checkpoint
The file name has no dot, and the rule has a fully qualified command path.
4. Validate the complete policy
Checking only the new line is not enough: an include, alias or later rule can change the effective result. Check the whole configuration (elevated, read-only):
$ sudo visudo -c
/etc/sudoers: parsed OK
/etc/sudoers.d/50-deploy-systemctl: parsed OK
Paths and wording vary by host. You want exit status zero and parsed OK for both the main file and the included rule.
Recovery
If the check fails, keep the administrative session open and inspect the reported file. Retrying the command that needs sudo will not fix a syntax error.
5. Test as the named user
Switch to the real account or a test login. As deploy, these are ordinary commands:
deploy$ sudo -l
Matching Defaults entries for deploy on this host:
...
User deploy may run the following commands on this host:
(root) /usr/bin/systemctl status ssh
deploy$ sudo -n /usr/bin/systemctl status ssh --no-pager
host-specific service status is printed here
sudo -llists what the policy allows.-nmakes the test non-interactive: it fails rather than prompting for a password, because a prompt can hide whether the rule matched.- A non-zero status is not a verdict. If authentication is required and no credential is cached, the command fails; that alone does not prove the command is unauthorised.
Tip
Use the exact command and arguments from the rule. sudo systemctl status ssh.service may not match an entry for ssh, depending on the actual argument matching. Check the listing rather than guessing.
6. Understand matching, then undo
This one surprises people: when several entries match a request, sudo applies them in file order and the last match wins, not the most specific one. A broad rule in a later file can quietly override your careful restriction, which is why the full sudo -l output matters.
To remove the example, first make sure the account has another administrative route and no active session depends on the rule. Then delete the one file with elevated privileges:
$ sudo rm -- /etc/sudoers.d/50-deploy-systemctl
$ sudo visudo -c
Warning
The deletion is irreversible unless you kept a copy, and it changes access immediately for new sudo decisions.
Tip
For a temporary rollback while investigating, you can move the file to a name the include directory skips, but only after checking your deployment's policy, and then validate the complete configuration. Do not leave backup files holding live privilege rules in /etc/sudoers.d; keep them outside that directory with permissions that suit your security policy.
Done means
- Safety net: you recorded the local sudo version and kept a recovery session open.
- Narrow rule: it names one account, target, fully qualified command and intended arguments.
- Right place: the rule is in a correctly named file under
/etc/sudoers.d. - Clean parse:
sudo visudo -caccepts the complete policy. - Effective permission:
sudo -lshows the expected entry for the named user. - Harmless test: the exact command ran without changing service state.