Module 3 · 3.2
English
sudo and least privilege
Module 3: Users, permissions and sudo · Reading time: 11 minutes
Learning objective: After this lesson you can work as a normal user with sudo, add an administrator safely, change the sudo settings without locking yourself out, and explain why least privilege protects your server.
Key concepts: sudo, sudo group, wheel group, /etc/sudoers, /etc/sudoers.d, visudo, NOPASSWD, sudo -l, locking root, sudo log, least privilege, service user
Why not just work as root?
After installation you often log in as root. That is convenient: everything is allowed. But that is exactly the problem:
- One typo is enough.
rm -rf / home/anna/oud(note the space after the first slash) wipes your entire server when run as root. As a normal user you get an error message. - Everything runs as root. A script you paste from the internet, a program you are testing: everything gets full permissions.
- No trail. If three people work as root, nobody knows afterwards who did what.
- Root is the name every attacker tries. You are better off switching root login off completely (lesson 2.2), but you can only do that once you have another route to administrator rights.
That other route is sudo: you log in as yourself and put sudo only in front of a command that needs administrator rights.
anna@web1:~$ apt update
E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)
anna@web1:~$ sudo apt update
[sudo] password for anna:
Hit:1 http://deb.debian.org/debian trixie InRelease
...(Since version 25.10, Ubuntu uses sudo-rs by default, a new implementation of sudo. For everything in this lesson it works the same way.)
sudo asks for your password, not root's. It then remembers it for fifteen minutes by default, so you don't have to type it for every command. Every command you run with sudo ends up in the log.
Creating an administrator
On Debian and Ubuntu, everyone in the sudo group may do anything through sudo. This is set in /etc/sudoers:
%sudo ALL=(ALL:ALL) ALLRead it as: members of the sudo group (%) may run any command (ALL) on all machines (ALL) as any user and group ((ALL:ALL)).
So adding an administrator takes two steps, as root:
root@web1:~# adduser anna
root@web1:~# adduser anna sudoThen put Anna's public key in /home/anna/.ssh/authorized_keys with the correct owner and permissions:
root@web1:~# mkdir -p /home/anna/.ssh
root@web1:~# cp /root/.ssh/authorized_keys /home/anna/.ssh/
root@web1:~# chown -R anna:anna /home/anna/.ssh
root@web1:~# chmod 700 /home/anna/.ssh
root@web1:~# chmod 600 /home/anna/.ssh/authorized_keysDon't forget the chown: when root copies the file, root owns it, and then Anna cannot log in with her key.
Now test in a second window, while your root session stays open:
anna@laptop:~$ ssh anna@192.0.2.10
anna@web1:~$ sudo -l
[sudo] password for anna:
User anna may run the following commands on web1:
(ALL : ALL) ALL
anna@web1:~$ sudo whoami
rootOnly when this works do you set PermitRootLogin no in your SSH settings (lesson 2.2). From then on you always log in as Anna.
One thing to remember: Anna now needs a password for sudo. Keep it in your password manager. Logging in uses the key, sudo uses the password: two different things an intruder needs to have both of.
Changing sudo settings: always with visudo
A mistake in /etc/sudoers can mean sudo stops working altogether. If root cannot log in either, you are stuck. That is why you never edit sudo settings with a normal editor, but with visudo. It opens a temporary copy and checks the contents before saving:
root@web1:~# visudo -f /etc/sudoers.d/backupJust like with SSH, use a separate file in /etc/sudoers.d/ rather than the main file. Keep two rules of that directory in mind:
- Files whose name contains a dot or ends in
~are skipped. Sobackup.confdoes not work, butbackupdoes. This is meant to ignore editor backup copies, but it catches a lot of people out. - The file must be owned by root and not writable by others (440 is usual; visudo takes care of this).
Want to check an existing file without editing it? visudo -c checks everything.
NOPASSWD: handy, but know what you are doing
With NOPASSWD, sudo no longer asks for a password:
anna ALL=(ALL:ALL) NOPASSWD: ALLSome VPS images set this for the default user, so you are an administrator straight after logging in with a key. Use sudo -l to see what applies on your server. The consequence: whoever has Anna's key is immediately root. There is no second lock any more. For a personal server you can choose this, but do it deliberately.
Much better is NOPASSWD for one specific command only, for example a backup script that has to run automatically:
backup ALL=(root) NOPASSWD: /usr/local/bin/maak-backupThe user backup may then run exactly that one script as root, without a password, and nothing else. Two pitfalls:
- Always use the full path. With just
maak-backup, someone can put their own program with that name at the front of their path. - The script itself must not be writable by that user. Otherwise they can change it and run arbitrary commands as root. The same goes for commands that can open a shell themselves, such as an editor (
vim,nano) orless: anyone allowed to start one through sudo can open a root shell from inside the program. Never hand out such commands on their own through sudo.
What gets logged
Every time someone uses sudo, a line is added to the journal (and on systems with rsyslog also to /var/log/auth.log):
anna@web1:~$ sudo journalctl _COMM=sudo --since today
Nov 09 10:31:02 web1 sudo[2214]: anna : TTY=pts/0 ; PWD=/home/anna ; USER=root ; COMMAND=/usr/bin/apt updateYou see who, where, as whom and which command. That is one of the reasons not to have several people working as root. Failed sudo attempts ("incorrect password attempts") from an account that isn't you are a warning sign.
Least privilege on a larger scale
sudo is one application of a general principle: least privilege. Every user and every service gets exactly the permissions it needs, and no more. On a server this means, among other things:
- you work as a normal user and only use sudo when needed;
- every service runs under its own user without a shell (lesson 3.1), not as root;
- a web application gets a database user that may only use its own database, not the administrator of the database server;
- a backup script may only run the one command it needs (NOPASSWD with a full path);
- a colleague who only updates the website gets write access to
/var/www/example.comthrough a group, not sudo.
The idea: if something goes wrong (a hole in a plugin, a stolen key), the damage stays limited to that one user or service. This comes up again and again in the CIS principles and the hardening lesson (10.1).
On AlmaLinux and Rocky Linux
There, the administrators group is called wheel instead of sudo: usermod -aG wheel anna. The rule in /etc/sudoers is %wheel ALL=(ALL) ALL. visudo and /etc/sudoers.d work the same way. Sudo messages are also found in /var/log/secure there.
Summary
- Work as a normal user and use sudo for administration; sudo asks for your own password and logs every command.
- Creating an administrator:
adduser anna,adduser anna sudo(wheel on RHEL-like systems), key with the correct owner and permissions, test in a second window, only then switch off root login. - Only edit sudo rules with
visudo, preferably in a separate file in/etc/sudoers.d/without a dot in the name. - NOPASSWD for everything removes a lock; preferably use it only for one command with a full path that the user cannot change.
- Least privilege: every user and service gets exactly what it needs, so a mistake or breach stays small.
Quiz
Exercise
Exercise O3.2: An administrator with sudo. Create a normal administrator on your server (for example anna), set up your key, test logging in and sudo -l in a second window, and then switch off root login over SSH (PermitRootLogin no). Tick off the steps, paste the output of id (name and groups only) and answer the questions: which rule gives your administrator its rights, is there NOPASSWD anywhere, and how do you get in if you forget your password?
Exercise O3.2: An administrator with sudo
You do this exercise yourself; no one checks it. Tick off what you've done and mark the exercise as done.
%sudo ALL=(ALL:ALL) ALL in /etc/sudoers (RHEL: %wheel). Use NOPASSWD only deliberately and preferably limited to one command. If you forget the password: use your provider's console, set a new root password via the panel or a rescue environment, then run passwd <gebruiker>.
Your ticks and notes only stay in this browser; we don't send them anywhere. If you're signed in, we only save in My courses that you've done the exercise.
Further reading
The steps in these articles apply to WebOké's VPSs; with other providers it works in a similar way.
- Securing your VPS: the first five minutes
- No access to your VPS anymore: what now?
- DirectAdmin guide 12.2: Database users, privileges and passwords
- Ubuntu Server: User management: https://ubuntu.com/server/docs/how-to/security/user-management/
- Debian manual page sudoers: https://manpages.debian.org/trixie/sudo/sudoers.5.en.html
