Many Linux servers still give whole teams sudo ALL, which is root for everyone. In this lab you audit the current sudo rights, write a drop-in policy that allows only the commands a role needs, close common shell escape routes, turn on command and session logging, and test that the rule set holds.
Key takeaways
- Audit first with sudo -l -U so you know what each user can run today
- Grant specific commands with full paths, never editors, shells or wildcards
- Always edit with visudo so a syntax error cannot lock you out
- Log commands and record sessions so privileged work can be reviewed
Why this lab matters
Privileged access management is not only vaults and expensive tools. On Linux, the first control is sudo, and it is already installed. Used well, it gives each role exactly the commands it needs and a record of every use. Used badly, it hands root to anyone in a group and logs very little.
What you need
- A disposable Linux virtual machine. Ubuntu, Debian, Rocky and AlmaLinux all work.
- An account with full sudo rights, and a second root session kept open in another terminal while you edit, as a safety net.
- A web server to manage. Install nginx with your package manager so the examples work as written.
Step 1: Audit current sudo rights
# who is in the admin groups
getent group sudo wheel
# every rule on the system
sudo cat /etc/sudoers
sudo ls -l /etc/sudoers.d/
# what one user can actually run
sudo -l -U alice
Write down every line that ends in ALL, and every line containing NOPASSWD. Those are your findings.
Step 2: Define the role
Create a test user and a group for a web operations role that may restart and check nginx and read its logs, and nothing else.
sudo groupadd webops
sudo useradd -m -s /bin/bash -G webops alice
sudo passwd alice
Find the real path of each command, because rules must use full paths:
command -v systemctl journalctl
Step 3: Write the rule with visudo
sudo visudo -f /etc/sudoers.d/50-webops
Add:
Cmnd_Alias WEB_SVC = /usr/bin/systemctl restart nginx, \
/usr/bin/systemctl reload nginx, \
/usr/bin/systemctl status nginx
Cmnd_Alias WEB_LOGS = /usr/bin/journalctl -u nginx --no-pager
%webops ALL=(root) NOEXEC: WEB_SVC, WEB_LOGS
Then check the syntax of everything and the file permissions:
sudo visudo -c
sudo chmod 0440 /etc/sudoers.d/50-webops
| Part of the rule | What it does |
|---|---|
| %webops | Applies to members of the group |
| ALL=(root) | On any host, run as root only |
| NOEXEC: | Stops the allowed command from starting another program, such as a shell |
| --no-pager | Stops journalctl opening a pager, which is a classic way to escape to a root shell |
Do not allow editors (vi, vim, nano), pagers (less, more), interpreters (python, perl, bash) or tools that can run other commands (find, tar, awk). Each can start a root shell. If someone needs to edit one file as root, allow sudoedit /path/to/file instead.
Step 4: Turn on logging
sudo visudo -f /etc/sudoers.d/00-logging
Defaults logfile="/var/log/sudo.log"
Defaults log_input, log_output
Defaults iolog_dir="/var/log/sudo-io/%{user}"
Defaults timestamp_timeout=5
Defaults use_pty
logfile records each command, log_input and log_output record the session so it can be replayed, timestamp_timeout asks for the password again after five minutes, and use_pty stops a background process from keeping the terminal after the command ends.
Step 5: Test the rule
su - alice
sudo -l # lists only the WEB_ commands
sudo systemctl restart nginx # allowed
sudo systemctl stop sshd # denied
sudo cat /etc/shadow # denied
sudo journalctl -u nginx --no-pager # allowed
sudo journalctl -u nginx # denied, the arguments do not match
exit
Denied attempts are reported in the system log:
sudo grep 'command not allowed' /var/log/auth.log # Debian and Ubuntu
sudo grep 'command not allowed' /var/log/secure # RHEL family
Step 6: Review the record
sudo tail -n 20 /var/log/sudo.log
sudo sudoreplay -d /var/log/sudo-io -l user alice
sudo sudoreplay -d /var/log/sudo-io <TSID from the list>
On a real system, forward these logs to a central log server so an administrator cannot edit their own history.
You are finished when alice can run only the listed commands, both denied tests appear in the system log, and you can replay one of her sessions.
Evidence to keep
- The before and after output of
sudo -l -Ufor the test user. - The two drop-in files.
- Log lines for one allowed and one denied command.
Clean up
sudo rm /etc/sudoers.d/50-webops /etc/sudoers.d/00-logging
sudo userdel -r alice
sudo groupdel webops Frequently asked questions
What does least privilege mean for sudo?
It means each user or group may run only the specific commands their role needs, as a specific user, instead of ALL commands as root. Everything else is denied and logged.
Why should I use visudo instead of editing sudoers directly?
visudo locks the file and checks the syntax before saving. A syntax error in sudoers can stop sudo working for everyone, which may lock you out of root access on the machine.
Why is allowing an editor through sudo dangerous?
Editors such as vi and nano can run shell commands or open any file. A user allowed to run one as root can easily get a full root shell. Use sudoedit for a named file instead.
How do I record sudo sessions?
Add Defaults log_input, log_output and an iolog_dir to the sudoers policy. sudo then stores terminal input and output, which you can list and play back with sudoreplay.