There was a time when real system administrators just logged into Unix systems as root. But as we all know — with great power comes great responsibility. It’s too easy to do terrible things when you are really just trying to do normal work, and, on top of that, malicious software or scripts can do naughty things without you noticing. So common practice quickly changed to where an administrator had a personal account but then had a way to run certain programs “as root” which means you had to deliberately decide to wield your power.
Before long, people realized you don’t even need a root login account. That way, an attacker can’t try to log into root at all. Sure, they could still compromise your account, but a random hacker knows you might have a root user, but it is harder to guess that your login ID is JTKirkJr or whatever.
There are other ways to control what users can do, but many Linux and Unix installations still use this model. The root can do everything but login, and specific users get the privilege to do certain things.
sudo
In the Linux world, sudo
is very common. It is a bit difficult to setup, but once configured, it is simple enough from a user’s point of view. If you want to, say, copy a file to a system directory, you prefix the command with sudo
:
sudo cp x.txt /usr/share/wherever
The sudo
program will validate your password (not the root password) or otherwise log you in (e.g., using a camera or smart key or whatever you have set up for PAM). Once you validate, you will stay validated for a short period of time so you don’t have to log in every time, although the time period is adjustable and can be turned off.
Where this is not simple is when you want to use redirection. For example, a common mistake is to write:
sudo echo y >/sys/option/made-up-option
This fails because sudo
only runs echo
as root. Your shell, the program that is interpreting the redirect, is still just you, and you can’t write to the/sys/option
directory. There are many workarounds for this. For example:
echo y | sudo tee /sys/option/made-up-option
There are a few options to sudo that you don’t often use, but probably should:
- -l — List. Shows what you can do
- -v — Validate. This refreshes the expiration time without running a command.
- -k — Kill. Ends the validation period now, so you’ll have to authenticate again when you use sudo.
- -u — User. Normally root, but you can impersonate other users with this option.
- -i — Interactive. Run a shell as though you’ve logged in as the user.
- -e — Edit. Edit a file as the specified user.
- -g — Group. Run as a group.
Configuration is a bit tricky. Also, if you screw it up too badly, you could prevent yourself from running root commands which is disastrous. Because of that, you shouldn’t edit the /etc/sudoers
file directly. Instead, you should use visudo
, which checks for sanity before overwriting your original file.
It isn’t a bad idea to open a root shell (sudo -i
) before you make any changes in another shell. You can also make a backup of sudoers
until you are sure your changes work.
Infrequently, you’ll want to change /etc/sudo.conf
, which allows plugins to change how sudo works. But, usually, the default with your distribution is what you want, and all the changes you’d like to make are in /etc/sudoers
.
The sudoers
file has a series of sections, many that set options or aliases. The lines you are mostly interested in look like this:
JTKirkJr ALL = (root) /usr/bin/ls
This means that the user JTKirkJr on any host (ALL) can run /usr/bin/ls
as the root user. One way to think of the structure is:
<who> <where> = <as_user[:as_group]><program...>
Sometimes, you want the “who” part to be a group. That’s easy:
%sudo ALL=(ALL:ALL) ALL
That means that anyone in the sudo group on any host can impersonate any user or any group for all commands. Easy! Sometimes, you want to run a trusted program as root without authenticating. This is very dangerous, so think hard before you do something like this:
JTKirtJr ALL=(root) NOPASSWD: /usr/bin/smidump
You may be able to add fragments to files inside /etc/sudoers.d
, depending on your distribution. You can find the entire manual for sudo
online.
If you try to do something you are not approved for, the “incident is reported.” Contrary to popular belief, the alert doesn’t go to the North Pole, but it is logged in /var/log/auth.log
.
su
Historically, many people used su
(which may mean substitute user, switch user, or super user) to gain a shell as another user (including root). That works, but it doesn’t have nearly as much control as sudo
. You get a shell, or you don’t. And if you do, you can do everything.
One difference between su
and sudo
is that sudo
wants your password. The su
command wants the password for the user you want to be.
run0/systemd-run
Of course, systemd wants to achieve world domination, so it has a way to do the same thing. Originally called systemd-run
and, as of, systemd v256, invokable as run0
to save a little typing and to set some default options to make it work more like sudo
. However, internally, it is different and leverages things like polkit and systemd, of course.
pkexec
Speaking of polkit, it also has a way — rarely used — to do a similar job. The pkexec
command lets you execute code as another user. As with all of these programs, there is a danger that allowing users to run programs as other users can open up security holes. Of course, you configuration is one source of these vulnerabilities, but in some cases, bugs in the program can create serious security holes.
The main use of pkexec
is to allow certain GUI programs to gain higher privileges when needed. Before that, kdesu
and gksu
however, you may find these programs still in use on older systems. There are also sudo wrappers like kdesudo
. You don’t see any of these in most newer distributions, though.
doas
If you don’t like sudo
‘s configuration file, you might want to borrow a program from FreeBSD called doas
. It also has a configuration file, but it is much easier to work with. The file to set up is /etc/doas.conf
. Some distributions include vidoas
to help with the editing.
The rule format is simple. Lines start with permit or deny, depending on what you want to accomplish. Then, you can name a user or group (with a colon prefix). You can add an “as” clause to specify a target user and a cmd keyword to specify a specific command.
For example, to let anyone in the sudo group do anything:
permit :sudo
That’s it. You can use options like nopass, persist, and others to manipulate the environment. So to get the persistent password, you might prefer to write
permit persist :sudo as root
Rooting it Out
You should be very careful changing anything related to how normal users can run programs as root. The potential for bad behavior is high. However, you do have to have something. Since run0
isn’t really widely available yet, we aren’t sure how useful it will be. We rarely see pkexec
in the wild. While sudo
is fantastically flexible, we do appreciate the simplicity of doas
.
Ultimately, they all do the same job. As usual with Linux, the choice is yours.