Should we use "sudo" for day-to-day activities?

18 July 2015

None of the systems I administer or supervise have sudo installed with the SUID bit set.

Every time I answer a question on how to do privileged work on these systems (i.e. do tasks that require administrator privileges) with a proposal to SSH under the privileged account directly to do such a work, whoever asked the question starts to blabber how insecure that is, that one should use sudo, and that nobody should ever login directly as root.

I have spent quite some time explaining the misconception behind so-called “secure way to access systems through sudo”, so I decided to write up an article that describes the issues of using that approach and why using sudo is actually less secure than a direct SSH access.

History

The following is based on my personal recollection of the history around early 90’s with some references to documents I could quickly find. Unfortunately, this is one of the topics that is not so easy to reconstruct in full detail. Although there may be minor inaccuracies, the outlined view on the history should be very close to the true events that took place.

Many years ago (but not that far in the past) system administrators were using telnet and rsh to access and administer their servers. Networks were simpler and traffic sniffing techniques were common. Therefore, it was very easy to eavesdrop on a root account login and to automate the task of gathering the credentials. To mitigate the issue to some extent the following approach was proposed:

  1. login as a non-privileged account first;
  2. do some stuff;
  3. if you need privileged account access (e.g. root) switch to it using su.

The idea behind this proposal was that such a sequence makes it harder for a traffic listener to catch root’s credentials on the wire due to the login sequence mixed in to the stream of other activities the systems administrator was doing before escalating their account to the privileged user.

At approximately the same time discussions started in regard to the dangers of working as root, that people were tending to work as root for prolonged periods of time performing tasks that did not require escalated privileges without proper justification for that behaviour. As the result of these discussions the sudo utility was born. The utility allowed to bind root privileges to a restricted set of commands and maintained access controls through its configuration file in order to allow or deny access to the defined functionality to specific users/groups. This allowed systems administrators to delegate some of the privileged routines to less privileged user/groups. (See more on the history of sudo if you are interested).

Somewhere in early 90’s the two approaches were merged, so the approach became:

  1. login as a non-privileged account and do your every day tasks;
  2. once a privileged operation is required execute it through sudo.

Although it seems like a minor optimisation, in fact, this introduced a major security issue: previously, the attacker should have needed to listen for traffic in attempt to figure out when the victim is executing su and is providing root’s password, but now they did not need to do anything except of capturing user’s password at the beginning of the session (the same problem the “su-after-normal-login” approach was trying to solve just reappeared :) ) since once you know user’s password you can use sudo which authenticates you with user’s password!

In 1995, Tatu Ylönen as a response to the issues related to exchanging the credentials over non-protected, easily sniffable networks released his first implementation of the SSH protocol as freeware to the public. Over the next five years SSH was adopted worldwide and it eventually replaced telnet/rlogin/rsh for the remote access and management activities in most places around the globe.

However, due to inertia the recommended approach of logging in as a non-privileged account and escalating privileges later somehow survived, is still followed, and often people don’t even try to analyse and see the flaws of the approach.

People are saying “sudo” is good. Is it true?

(or looking critically into some common misconceptions re: “sudo”)

So let’s look at the most commonly used “pros” in favour of using sudo. For example, Ubuntu’s community help page provides a nice, aggregated list of benefits provided by sudo usage in their default installation. Let’s walk through all of them and see if they are real benefits at all:

  1. The installer has fewer questions to ask.

    This is a very questionable “benefit” to the end user since it implies that the system would do more stuff with escalated privileges behind the scenes without the user even knowing it. From the security standpoint it just silently expands the attack surface.

  2. Users don’t have to remember an extra password for occasional use (i.e. the root password). If they did, they’d be likely to forget it (or record it unsafely, allowing anyone to easily crack into their system).

    This is another hard to comprehend “benefit”. Given that we now have SSH and the recommended best practice is to use SSH keys instead of passwords, sudo requires users to memorise yet another password.

    Moreover, the argument in regard to users’ likely behaviour is purely speculative and assumptive — to the same extent we can assume that password policies make it hard for users to memorise their passwords and they would be likely to forget the password (or record it unsafely, …).

    The truth is, the key based authentication solves the issue of the requirement to have multiple passwords for multiple accounts.

    There is one place, however, where the discussed “benefit” is actually applicable — local console access (no key authentication there, usually), but even there the best practice would be to login directly as root on the virtual console if there is such a need (the reason for that is quite complicated and in short could be described as the following: there are multiple checks and assumptions in the kernel code and the accompanying C library on allocating a terminal, spawning a process, etc. for root over the same actions performed for a non-privileged user).

  3. It avoids the “I can do anything” interactive login by default. You will be prompted for a password before major changes can happen, which should make you think about the consequences of what you are doing.

    This statement also assumes that for some reason people would prefer to always login as root and do all of their work under that account.

    In reality users are so used to prefix almost any failed command with sudo that this “benefit” can be considered as the quite opposite item, against sudo.

    On a properly configured environment you explicitly need to login as the privileged account to do functions that require privileges.

  4. sudo adds a log entry of the command(s) run (in /var/log/auth.log). If you mess up, you can go back and see what commands were run.

    This statement is also somewhat true, but it does not defend the sudo usage. A proper auditing subsystem is what keeps audit logs no matter how activity was performed. Logging of executed commands for user’s history reasons is the job for the shell.

    The ability of logging is so limited in sudo that it cannot be used for anything except a substitute for the shell history. Just imagine the following scenario — a user executes:

    sudo less /var/log/messages

    and then types “!” followed by the Enter/Return key — the user effectively now in the root shell and what sudo will log into its logs has nothing to do with what user actually did.

    Instead of relying on sudo‘s logging abilities, one should configure auditd and send events to a centralised log aggregator to get audit logs that can be trusted.

  5. On a server, every cracker trying to brute-force their way in will know it has an account named root and will try that first. What they don’t know is what the usernames of your other users are. Since the root account password is locked, this attack becomes essentially meaningless, since there is no password to crack or guess in the first place.

    This is such a weak attempt to bring host security into the play that it is hard to comment on it without dropping a tear :).

    First, use SSH keys and disable the password authentication on the server — this (and not some security through obscurity) will defend the system from the brute force attacks.

    Second, protect your remote access entry points with properly configured firewall and allow remote access from a defined list of locations only (i.e. whitelist authorised locations) — this will shrink the possible attack surface of the SSH service considerably.

  6. Allows easy transfer for admin rights by adding and removing users from groups. When you use a single root password, the only way to de-authorize users is to change the root password.

    This is an interesting one: half of the statement is true, another is misleading.

    The true part is that you can easily delegate privileged operations using sudo. All in all, it was the primary goal and requirement of the tool creation to provide access delegation.

    The misleading part is that the alternative is to use a single root account/password. The truth is that nobody is limited by a single root account: you can create as many as you want and each of them could have their own distinct password, e.g.

    [root@localhost ~]# useradd -om -o 0 -g 0 -s /bin/sh new_root
    [root@localhost ~]# passwd new_root

    Better yet, do not set the password and lock the account instead with usermod -L new_root since we are using keys, remember?

    This approach also provides additional accountability since users will have separate shell histories, their login attempts will be clearly logged under separate names, etc.

  7. sudo can be setup with a much more fine-grained security policy.

    Another half-truth in the list of “benefits”. The statement is incomplete and lacks the part it is comparing the functionality to. If we are comparing a legacy Unix access control system with sudo, then yes sudo is much more configurable. If we compare sudo with, say, SELinux or GRsecurity’s RBAC – sudo will lose since both have much more fine-grained security controls than sudo.

  8. The root account password does not need to be shared with everybody who needs to perform some type of administrative task(s) on the system (see the previous bullet).

    As with item #6 this statement assumes for some obscure reason that there can be just a single root account in the system. Therefore, the result of such a logical exercise is also questionable since it is based on a wrong assumption.

  9. The authentication automatically expires after a short time (which can be set to as little as desired or 0); so if you walk away from the terminal after running commands as root using sudo, you will not be leaving a root terminal open indefinitely.

    This statement also compares sudo with something reader cannot compare to. Moreover, it mixes up two logically unrelated things: the credentials expiration and terminal security. While it is great that sudo implements the former, the latter is usually addressed by entirely different means: starting with auto-logout functionality, lock screen, physical security, etc.

Well, we can continue to critically assess other common statements in regard to sudo made mostly by people who do not have any strong Information Security background, but it would be a waste of time for the readers.

You can always raise a question regarding some particular claim and/or assumption related to sudo and if it is interesting I would add it (and the corresponding response) to this article.

What is the problem with the “sudo” approach?

Well, there are several in fact. The most pressing issue is that the usage of sudo (or su, or any other utility that has its SUID bit set) is crossing the security boundary from the less privileged account to the more privileged account. This opens doors (or widens the attack surface) to privilege escalation techniques. In plain English it makes the non-privileged account to be essentially equal to the privileged one, let me explain by a fairly simple example:

  1. imagine if you are a developer and you work on a server under your non-privileged account;

  2. as a part of your daily routine you need to download some third party package and install it (we are going to leave out all the security complexities involved with such an activity like verifying signatures, using a separate instance to prepare a package for deployment, etc.);

  3. the installation of the package usually requires executing some third party code under your non-privileged account. This code was not written by you and there is a high chance that you did not read/verify the foreign code line by line in order to ensure that it does not do anything malicious since this would be quite time consuming, would require a lot of effort, and your team has more important priorities than this (remember, this is an example based on situations you would encounter in the real world, which is by no means perfect);

  4. it happens, that that particular third party was compromised and some malicious code has been injected into the package installation routines;

  5. after the execution of the installation routine (and the malicious code for that matter) your ~/.bashrc (for example) is modified in such a way that each time you login it starts up a key logger or some other kind of remotely controllable piece of software that talks back to its master;

So far we just got an issue localised to this non-privileged account only (with a possibility to spread across the entire fleet of servers that non-privileged account has access to in case of the NFS mounted home directories). Is this bad? Yes, it is since it may disrupt this particular project, steal reachable sensitive information, could be used as a trampoline to jump start further research and exploitation of other vulnerable resources. Is it critically bad? Not necessarily. If the systems are built properly with host-based security in mind, if the proper privilege separation techniques are used throughput the company infrastructure, etc. the impact is localised and with proper monitoring systems it would be detected eventually and investigated (keep in mind that it is really hard for a non-privileged account to hide their activities from more privileged processes).

Now, let’s add sudo to the mix, e.g. suddenly the developer decided to install an additional library package into the system. So, what would happen next? You guessed it: the developer would need to type in their password to convince sudo that they are “allowed” to do such a privileged thing as installing a system package, the malicious software installed by the attacker would happily intercept that and send it back to its master.

From this point on, the attacker has the account password of the account where their software runs and which they control. The attacker can now utilise sudo powers at their will. The security impact would be ranging from “high” to “extreme” depending on how committed the attackers are.

Following the logic, why would we want to introduce an additional complexity that does not address the issue it was supposed to address, which is “to limit exposure of the root account”?

The light side of “sudo”. Is there one?

So, is sudo any good for anything? Actually, yes, it is. All in all, sudo is a tool that attracts a lot of attention from the security researchers and auditors, its codebase got numerous peer reviews and the functionality the tool provides can be used for good. The following scenarios come to my mind right away:

  • On a SELinux enabled system it seems that sudo is the only properly implemented and reliable way to assume a different SELinux role. All other mechanisms are either lacking in the functionality or just do it half way leaving some artefacts behind;

  • Unless some effort is put into tweaking the way PAM (Pluggable Authentication Modules, an authentication framework used on Linux, Solaris, and some other Unix-like systems) authenticates users on LDAP enabled systems there is no easy way to have two separate accounts (a privileged and a non-privileged account) for the same LDAP user. This could be addressed administratively (e.g. by defining additional privileged users in LDAP) or technically by implementing account names’ prefixes. However, if there are budgetary and/or time constraints to implement the proper security framework sudo with a quite restricted configuration would be an acceptable compromise.

Unfortunately, personally, I failed to find any other justified applications of sudo in a secure environment and would be happy to get some feedback if you have something in mind worth including into the list above.

How can we improve the security of our systems in relation to the “sudo” usage?

OK, so we got to the point where we are standing at a crossroad and we kind of established that excessive usage of sudo is a bad thing (for security-paranoid readers - read: “almost any usage of sudo except for changing SELinux roles on a SELinux-enabled system is a bad thing”). So, what is the alternative way of doing things? Well, there is a complex approach on addressing and minimising the privilege escalation risks and roughly it can be summarised as follows:

  • apply the least privilege principle to everything

    For example, if you need to work on content, the account you use to log into the remote server should be allowed to do just that. This sounds a bit extreme, so we may re-phrase it as follows:

    Each account should be provided the least number of required privileges to do specific tasks under that account and should not be used for anything else outside the defined set of activities.

    Again, if you include “becoming root” into the list of defined activities it would kind of defeat the purpose, so please resist this temptation. :)

  • there should be a defined list of accounts which are allowed to do system-wide modifications (e.g. privileged accounts)

    In line with the previous bullet point, these accounts must be used for these activities only (system updates, installing new software, modifying system-wide configuration). The expectation is that the privileged accounts are used on occasion only;

  • privileged accounts during their activities should not cross the security boundary with the less privileged accounts.

    This is needed to avoid attacks from the less privileged accounts toward more privileged (e.g. process hijacking, file races, etc.). Unfortunately, this point is a bit confusing without a proper explanation that may take several blog posts to be fully covered, but in a nutshell it means that root should not touch anything writable by the less privileged account. Some examples of the bad and insecure behaviour include:

    • changing directory to a directory writable by non-root,
    • executing scripts from a directory writable by non-root accounts or scripts that are writable by non-root,
    • copying a file/directory from/to a directory writable by non-root accounts,
    • and so on.
  • if possible (and this is highly recommended) privileged accounts should be accessed from the trusted and secure machines.

    It is really hard to define what the “trusted and secure machine” is, but generally it should be assumed

    • that it is a laptop or a desktop station that is used entirely for the work purposes (no free time surfing on the leisure sites and stuff :) ),
    • that proper firewall rules and protection techniques were used to secure the machine, and
    • that the operator is security-minded and does everything they can to ensure integrity and security of their machine and software installed on it.

I would be really happy to answer any question in regard to this article and provide any possible help in making our everyday system level activities more secure, so do not hesitate to comment or contact me.