Thursday, December 11, 2008

Sudo vs. Root: The Real Story

In Mac OS X, the root account is disabled by default. The first user account created is added to the admin group and that user can use the sudo command to execute other commands as root. The conventional wisdom is that sudo is the most secure way to run root commands, but a closer look reveals a picture that is not so clear.

note: originally published March 21, 2006 on my old site, linuxboxadmin.com

What you get with sudo

What are you really gaining by using sudo in the default Mac OS X configuration? First, you gain some comfort that nobody can login as root, either locally or remotely via SSH or FTP and tamper with your machine. Second, you get a log entry in /var/log/system.log every time sudo is used showing you who used it and what command was executed. These appear good enough reasons to endure the slight inconvenience of using sudo.

However, the way sudo is configured out of the box, you only need to enter your own password for authentication. This means that if someone guesses your password or steals it (and has access to it locally or via SSH), they can take over your box just as if you had root enabled.

Worse, if you execute sudo -s to start a root shell, the only thing that shows up in your system.log is this:

Mar 20 07:49:12 my-mac-mini sudo: username : TTY=ttyp3 ; PWD=/Users/
username ; USER=root ; COMMAND=/bin/bash

Every other command after starting a root shell does NOT get logged at all. All you can tell from this is when someone started the root shell. Whatever happened after that is a mystery. The same problem exists if a command is executed that permits shell escapes like many text editors, telnet programs, etc. So, in fact, using sudo has gained us absolutely nothing over enabling and using root.

These deficiencies can be mitigated, and we'll get to that later.

Securing the root account

If you enable the root account, there are a couple of precautions you should take. First, give root a different password than your user account.

You can prevent root logins to SSH by changing this line in the sshd configuration file, /private/etc/sshd_config:

#PermitRootLogin yes

to this:

PermitRootLogin no

To go one step further, disable all password logins to SSH and allow only public key authentication. This is how I configure my Linux servers. There are many fine resources on the web that describe the gory details of using SSH public key authentication.

FTP logins by root are disabled by default since the root account is listed in the /etc/ftpusers file. Users listed in that file are not allowed to login using FTP.

Finally, disable user access to sudo by commenting out the %admin line in /private/etc/sudoers:

#%admin ALL=(ALL) ALL

With two minor configuration changes, we have a system that is arguably more secure than the default system using sudo. Why? Because if someone guesses or steals your user password, they can't use sudo to take over the machine. They still have to guess the root password. Of course, if they have a local account, they may be able to use a privilege escalation vulnerability to gain root access, but that is an issue for Apple.

Back to sudo

Is there a way to make the sudo configuration more secure? There are many things that can be done to improve the default settings. Here are a couple.

The most obvious change is to require a different password than your user password to authenticate. This can be done while keeping root logins disabled with a little trickery. First, enable the root account, change the root password, then use Netinfo Manager to change the root shell to /usr/bin/false. Any attempt to login as root will immediately end. Then, you can force sudo to require the root password by adding this line to /private/etc/sudoers:

Defaults:ALL rootpw

Another security enhancement is to set up restrictions by user, and listing specific commands that are allowed to be run using sudo. By limiting the commands that can be run, you can limit the damage that can be done by a user account. This means changing the line in /private/etc/sudoers that grants all commands to users in the admin group. Check the sudoers man page for the details.

With these changes in place, sudo becomes much more secure, and is probably safer than using root directly. You should still change the SSH configuration to deny root logins and use public key authentication.

The real story

I've made arguments and suggestions for using the root account and for using sudo. But consideration should be given to the role of the computer and primary user(s) before making a decision on which may work best for you.

The main goal of sudo is to allow users limited access to root commands for the purpose of distributing the sysadmin load. On a single user box, you are only distributing the load to yourself. If you take a few precautions, enabling the root user is perfectly acceptable and can be more secure than the default configuration using sudo. On a multi-user box, sudo adds value and may be the best way to go. Given its limitations, the notion that sudo is always the best choice is dubious. The real story is it depends on the configuration.