Penguin

A short guide to setting up sudo(1)

sudo is configured in the /etc/sudoers file, which is documented in sudoers(5)?. That man page is somewhat daunting at first, as it uses an EBNF to describe the configuration, however there are good examples near the end which cover most typical requirements.

Please make sure you read the security section at the end.

Configuring sudo

Be aware that sudo(1) is very picky about correct syntax in its configuration file and will refuse to work if you make the slightest mistake. (Considering that sudo(1) can grant SuperUser privileges, this is not an entirely bad idea, user-unfriendly as it may be.) Therefore, you should use the visudo(1)? tool to edit the file, rather than opening it directly. visudo will check your changes for correctness after saving them, and will inform you of any errors, in which case it will offer to reject the changes or re-edit the file. Of course, visudo itself requires SuperUser privileges, so launch it using su -c visudo.

Note that visudo may insist on making you use vi(1) to edit the file, though some configurations may respect your choice of TextEditor according to the EDITOR/VISUAL EnvironmentVariables. If this bugs you, edit /etc/sudoers with another editor, then use visudo -c to check it for correctness. (You can add an incantation to /etc/sudoers to tell visudo what EDITOR/VISUAL settings to respect, but that's pointless to discuss here since most people are only ever going to edit the file once.)

Sudo and passwords

Sudo operates in two modes with respect to passwords – it needs them or it doesn't. The NOPASSWD configuration token states that no password is needed for this block – if that token is not present, the user will have to type in their password.

Note that sudo does not escalate any priviledges for the original user. All priviledged commands must still be executed through the sudo command.

Which password?

Sudo requires the user that is calling sudo to enter their password. This is an important disctinction, because it means you can delegate administrative responsibility to users without having to supply everyone with the root password.

Password Caching

Sudo's default configuration is to cache a password for 5 minutes. This does allow some possibility of a security hole; see notes below for more details.

Notes on examples

The following sections all assume a couple of things:

  • You are using visudo (or a similar program) to edit /etc/sudoers. See the notes above for more information on this
  • There are two users, jack and jill, on the machine
  • jack is a member of the unix group wheel, jill is not
  • jack and jill are both members of the unix group users
  • I use the whoami(1) command, because it reports the user ID, and is therefore effective in showing the change in privilege.

Basic format

The basic format of the user specification in the sudoers file looks like:

user hostlist = (userlist) commandlist
  • user is the name of the user or group to which this rule applies
  • hostlist is a list of hosts this rule applies to
  • userlist is a list of users that this rule can be run as. and must be enclosed in ( )
  • commandlist is a list of commands that this rule states can be executed

The userlist token is optional – if excluded, it defaults to root.

All three of hostlist, userlist and commandlist can be replaced with the token ALL, allowing unrestricted access in each situation.

Setting sudo to allow a user to run commands as root

This is the most common usage of sudo – it lets a specific user run all commands as the root user, without having to know the root password. Many modern linux distributions (such as Ubuntu) configure this by default for the first user of the system.

jill           ALL = ALL

This says that the user jill will be able to execute all commands as root from all hosts. Jill will be required to enter her password.

Setting sudo to allow a group to run commands as root

It is useful to configure sudo to allow an entire group of users, such as the wheel group, to run sudo. Rather than having to configure sudo each time you wish to add or remove a user, you merely keep the group list updated.

%wheel         ALL = ALL

This says that all users in the group wheel, eg jack, will be able to execute all commands as root, from all hosts. Jack will be required to enter his password.

Setting sudo to not require a password

In many situations people wish to not have to enter a password. This is useful if you are the only user on the machine, or if you really trust your admin users and know that they keep good security with respect to their passwords, accounts, SSH keys, and so on.

%wheel         ALL = NOPASSWD: ALL

This lets all users in the wheel group run all commands, from all hosts, without having to enter their password ever. Note that they still have to use the sudo command!

If you don't wish to deal with groups, you can of course substitute a username in for the %wheel token:

jack           ALL = NOPASSWD: ALL

Only allowing a user to run a particular command

There are plenty of situations in which you might want a user to be able to run a command, or a list of commands, but not to have full access to the system. For example, you might wish to let any user on the system run the pon and poff commands, to bring a dialup link up or down on demand.

%users         ALL = NOPASSWD: /usr/bin/pon, /usr/bin/poff

This lets all users in the unix group users run, without entering a password, the commands /usr/bin/pon and /usr/bin/poff.

It's important to provide a complete path, as if you merely include the executable name, a user could gain root access through malicious code execution.

Running commands as a different user.

Sudo lets you run commands as the root user by default – but you can also configure it to allow you to run commands as any user. To do this we add another token to the configurations mentioned above

eg:

%users         ALL = ALL

Will let all users in the unix group users run all commands as root, but not as other users:

$ whoami
jack
$ sudo whoami
root
$ sudo -u jill whoami
Sorry, user jack is not allowed to execute '/usr/bin/whoami' as jill on localhost.localdomain.
%users         ALL = (ALL) ALL

Will let all users in the unix gorup users run all commands as all users:

$ whoami
jack
$ sudo whoami
root
$ sudo -u jill whoami
jill

Use this wisely! Of course, if you allow a user to run any command at all as root, they can always change to another user anyway.

Command and Host aliases

Sudo allows you to specify lists of commands and hosts to use instead of having to type out each one each time. I'm not going to cover host aliases, because they don't really apply to single-user or per-host configurations of /etc/sudoers. Read the man pages if you want some examples.

Command aliases

A simple command alias might look like the following:

Cmnd_Alias      SU = /usr/bin/su

You can provide a list of commands, of course:

Cmnd_Alias      SHELLS = /usr/bin/sh, /usr/bin/csh, /usr/bin/ksh, \
                               /usr/local/bin/tcsh, /usr/bin/rsh, \
                               /usr/local/bin/zsh

These can be used in place of the commandlist token

Restricting commands

You might wish to allow users the ability to run most commands, but to restrict a few. Eg, let's say you don't want your users to be able to run the 'su' command, or to execute a shell, as the root user.

This requires the SHELLS and SU command aliases are configured, as per the previous section of this document.

%users         ALL = ALL, !SU, !SHELLS

Usage of sudo

If sudo has been configured to not required a password for the particular command you are trying to execute, it will “just work.”

If the NOPASSWD token has not been set, you will be prompted to enter your password the first time you try to execute sudo

$ sudo whoami
Password:
root
$ date
Sun Aug 28 10:05:44 NZST 2005

Sudo is configured by default to cache your password for some time, such as 5 minutes. Note that this counter is reset every time you run sudo. Consider it a 'time since last used'. If you run sudo again within this time, you will not be asked for a password:

$ date
Sun Aug 28 10:06:13 NZST 2005
$ sudo whoami
root

And if you then wait for 5 or more minutes, and try again, you will once more be asked to enter your passwd:


$ date
Sun Aug 28 10:06:13 NZST 2005
$ sudo whoami
Password:
root

Note that the password caching applies for the user calling sudo only. It is not, by default, restricted through any other mechanism such as the TTY you are logged in on, or the command you are executing:

$ sudo whoami
Password:
root
$ sudo touch /root/newfile
$ sudo chmod 0600 /root/newfile
$ sudo ls -la /root/newfile
-rw-------  1 root root 0 Aug 28 10:09 /root/newfile

Security and sudo

sudo does not allow unverified SuperUser access to a normal user

When you wish to execute commands as root, or as another user, you must still use the sudo command:

$ sudo whoami
root
$ whoami
jack

sudo does not grant SuperUser access to users.

It grants access to particular commands to users. Only the permitted commands can be subsequently invoked via sudo by the originally invoking user.

Is sudo a security hole?

Some people perceive sudo as a security flaw in a system. In practice, it's not really much worse than giving people the root password. Consider the following scenario:

An attacker discovers the password of an administrative user account (jack) on a machine. He can use this to log into the machine directly. He discovers that jack has sudo access, and can now completely take over the machine.

Seems quick, huh? This isn't really a problem with sudo, as much as a problem with jack's poor password security. What might have happened otherwise? Consider this:

An attacker discovers the password of an administrative user account (jack) on a machine. He can use this to log into the machine directly. After logging in, he discovers that the kernel is vulnerable to a local root escalation exploit, and so he downloads and compiles an appropriate rootkit, executes it, and can now completely take over the machine.

Slightly more work, but you have to consider that people who break into machines already have these tools available. How about another couple of situations:

An attacker discovers the password of an administrative user account (jack) on a machine. He can use this to log into the machine directly. He checks through jack's .bash_history file and notices a random-looking sequence of characters the line before 'su' is executed. He runs 'su', and uses this sequence of characters, and his hunch pays off – he now has a root shell on the machine.

An attacker discovers the password of an administrative user account (jack) on a machine. He can use this to log into the machine directly. He checks the kernel, it is not vulnerable to any known local root escalation exploits. He instead downloads a trojaned version of the 'su' command to the machine. This program will intercept the user's attempt to authenticate with the root password, storing the password, before passing it all on to the real version. The hacker then modifies jack's PATH to include this binary before everything else, so that when jack runs the 'su' command, it will run the trojaned version. The hacker receives an email from his program a day later – jack has used the trojan su command, and given away his root password. The hacker can now completely take over the machine.

Whether any of the above scenarios are feasable or not is another matter – the point is that once an attacker has a local shell on your machine, all bets are off. It is almost certain they will have installed a trojan somewhere, or will have already gained root already through other mechanisms. Sudo doesn't really make this much worse.

That said, there are some practical things you can do to increase sudo security

Decrease the cache timeout:

You can set sudo to expire its password cache sooner than the default 15 minutes, by setting the timestamp_timeout option to something else in /etc/sudoers.

Force expire your password token:

If you know you have finished using sudo for now, use sudo -k to expire your tokens right now. This could be included in a .bash_logout script to force expiring tokens when you logout of a machine, or your screensaver could be configured to execute it for you.

Prevent TTY attacks

sudo doesn't care about which TTY you are logged in on by default. Eg., if I login on one console, run sudo and enter my password, then login on another console, and run sudo again, my password is already cached. This could be bad if you left yourself logged in elsewhere by accident – say on another machine.

sudo can be compiled with the USE_TTY_TICKETS option, which will limit a ticket to a particular TTY. Not many distributions seem to do this however.

References


CategoryHowto