Linux Fu: The Root Cause

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

XKCD #149 (CC by SA 2.5)

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.

XKCD #838 (CC by SA 2.5)

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.

22 thoughts on “Linux Fu: The Root Cause

  1. i am still happy with su and sudo. i don’t really believe the ‘safety’ of sudo’s limitations is more than an illusion but sometimes it’s the convenient tool anyways.

    but recently i ran into capabilities. i wanted to set up a tunnel (fake ethernet device) and looked into giving my user account CAP_NET_ADMIN, but to my surprise the thing worked even before i finished setting up the account-level capability. i eventually figured out, it has a helper binary squirreled away somewhere that has the capability set ‘cap_net_admin+ep’. like the old setuid root, but it just gives it the capability instead of full root. so it’s decently safe.

    it’s pretty slick, and in some ways it’s straightforward how it works. but i don’t like how opaque it is. i have to know “getcap ” to even know it is special. it doesn’t show up special in ls. and i didn’t run into it on this excursion, but i know from experience that somewhere there’s a massive library of default selinux settings which is astonishingly overcomplicated, and just as opaque. i’m not sure what the best remedy is, but at the moment it feels like a hack scabbed onto unix from the outside, rather than a part of the system.

    the other thing is, it’s so “decently safe” that this is the default installation! so if i install this package, then by default any unprivileged user on my system can break my network configuration! what! i used to “find / -perm -4000” so i could audit all of the setuid programs installed by default. but this one really snuck up on me

  2. “As usual with Linux, the choice is yours.”

    As usual with Linux, I use the way I think I know but still find myself trawling through screenfuls of opaquely-written man pages displayed in a mono font as if it was still 1970!

    1. What!
      Are you trying to say that the lowest common denominator for most of the most advanced utilities in GNU/Linux is still a simple stone-age shell from the land before time with an interface that has not significantly improved in >20 years?

      The audacity! /s

  3. “{I} don’t really believe the ‘safety’ of sudo’s limitations is more than an illusion but sometimes it’s the convenient tool anyways.”
    Same here. If you ‘break’ a user account you automatically get all his/her sudo privileges as you already have the user’s password. And since the first user usually has admin rights, you have access to the entire system. I haven’t decided yet, but thinking I need to disable sudo entirely (or really limit it) once I have given root a good password.

    First thing I do setting up a new system is give root a password. ‘sudo passwd root’ . That way I can then use the standard ‘su -‘ command and do things as root. Of course I do not allow ssh/ftp/sftp/etc. access via root. You have to be logged in as a normal user before you can attempt getting to root. That makes sense to me. sudo is nice for quick things like ‘sudo apt update’ , but when you have to need to crawl around the system changing/editing stuff ‘su -‘ is the ticket. Stay root until done, then ‘exit’ back to normal user.

    1. On enterprise systems you would disallow su and allow only sudo, because of audit trail. If you and other user are logged in and both run su – and one of you breaks the system, it’s very difficult to identify who did it. With sudo, it’s easier to know who did “sudo chmod -R a-r $SOMETHIG/” and broke everything because $SOMETHING had a value but SOMETHIG not. Same for logging in as root, if root kills the server, who was behind root?

      And we had a rule (never enforced) that anyone caught running “sudo su -” would have to pay pizza for the entire team.

      But my personal servers have a long, password manager generated password for root. I am the only user, so if I break the system, I will be able to convince me that I was the one that broke the system and make me fix it…

      1. On enterprise systems, what would normal users ever need sudo or su for? Only the system admins would be allowed to do things to the system located in the back room. I would think anyway. And I think the system admin(s) would coordinate with each other and get a documented ‘ok’ from the group leader before proceeding with any changes — unless working in an ad-hoc, go for it, shoot from the hip, environment. When I (and a couple of others) were admins at work, we’d coordinate what we were doing to our file server. Of course at home, I am the only admin our systems.

        1. On enterprise systems you have a team of sysadmins. You don’t have a random Joe SSH into the servers and try to run things.

          You have the “sysadmin” users that can “sudo anything,” application users that can use sudo to start or stop application servers, database admins that can use sudo on a few database utilities, and so on. That’s why on the sudoers file you can specify what which group can execute.

          > And I think the system admin(s) would coordinate with each other and get a documented ‘ok’ from the group leader before proceeding with any changes

          There’s theory, there’s practice. It’s easier to someone to “forget” about the accepted change management plan, and execute something that wasn’t planned, or even execute something on a production server thinking it was on dev/test server. That’s why you never ever allow “sudo su -” and only have “sudo vim /etc/something” and “sudo mv /something /something-else.” With sudo you know exact what was executed and who did it.

          Usually nobody reviews /var/log/sudo.log or /var/log/auth.log, but when a change breaks something, it’s a nice target. And if you used “sudo su” you would usually have to face the “change management” management.

          We are required to do training every year about how to use our powers. As someone said, “your company is as secure as the sysadmins” and “with great power comes great responsibility.” Executing the wrong command, or the correct command at the wrong time
          or wrong server can be devastating…

  4. I’m the only person to use my system, and all too often I have to run privileged commands. It’s too much trouble to do anything but run as root. I’ve even modified and recompiled programs that refuse to run as root. 23 years and no problems.

    1. I like to run everything very close to completely stock, so I almost never have to run anything as root. Really just apt-get and snap install, and sometimes shutdown, if I’m not just GUIng it.

  5. A real quality of life feature for me is sudo -E (preserve environment). So everything you spent so much time to configure as a user still feels the same, e.G. your fancy neovim, your htop,…

  6. Every so often something complex comes up that becomes cumbersome to use with sudo, too many commands, or a bunch of pipes or whatever, and I decide I’m better off to run it as root. Instead of worrying about a root password, I just `sudo su`.

    This works equally well when I need to log in as another user that either doesn’t have a password, or I’m simply too lazy to open a fresh terminal. `sudo su `

    Both cases let me use my own password, instead of whatever password the target use may or may not have.

  7. During the 1980’s at NCR, the QA group knew root’s password for the various UNIX systems because we needed to administer the systems. One person in the QA group that wasn’t involved in testing hardware or software wanted root’s password. I couldn’t trust that he may accidentally do something that may harm the system. I created an su shell script in /usr/bin that prompted “Enter password:” and also turned off echo, and changed the prompt from ‘$’ to ‘#’. I edited his profile to look in /usr/bin before/ bin, wrote something on a Post-It note and gave it to him. He was happy.

  8. As the co-author of sudo, I am stunned and amazed that a program we created some 40 years ago still gets used. It was written back in the day when dozens of users shared one machine. Today, its role is ceremonial; It acts as a syntactical reminder to think twice about what you are about to do. BTW) The sudoers file was done by someone else later and I agree with anyone who thinks it is awful.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.