Previous Page
Next Page

8.5. Using sudo to Delegate Privilege

Sometimes it's useful to delegate superuser privilege to a Fedora user; however, giving him the superuser password gives him total control of the system. The sudo system enables superuser privilege to be delegated on a program-by-program basis.

8.5.1. How Do I Do That?

There are two parts to sudo: the /etc/sudoers file, which controls who can do what, and the sudo command, which enables authorized users to run commands with superuser privilege.

To configure /etc/sudoers, use the visudo utility, which will start vi so that you can edit the file. When you are done, it checks the syntax before installing it. If there is a syntax error, visudo will prompt you for a course of action; to see the available options, enter a question mark:

# visudo
>>> sudoers file: syntax error, line 17 <<<
What now? ?
Options are:
  (e)dit sudoers file again
  e(x)it without saving changes to sudoers file
  (Q)uit and save changes to sudoers file (DANGER!)

What now? x

To enable the user chris to run the netstat and ifconfig commands as the superuser, add this entry to the sudoers file:

chris ALL=/bin/netstat,/sbin/ifconfig

This entry contains the username, the computers (in this case, ALL) on which this user can execute this command (useful if the sudoers file is shared among several machines, either through a file-sharing protocol or by copying the file), and a list of commands that may be executed as root.

Be careful selecting the commands to include in the list: if any of the commands permit access to the shell, the user will be able to execute anything!

Once this change has been made, the user chris can use sudo to execute the netstat command using the -p option (which requires superuser privilege to operate correctly):

chris@bluesky$ sudo netstat -ap
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address          Foreign Address  State       PID/Program name
tcp        0      0 *:sunrpc               *:*              LISTEN 1488/portmap
tcp        0      0 laptop3:smtp           *:*              LISTEN 1724/sendmail
tcp        0      0 laptop3:x11-ssh-offset *:*              LISTEN 20494/2
tcp        0      0 *:42365                *:*              LISTEN 507/rpc.statd
tcp        0      0 *:http                 *:*              LISTEN 21393/httpd
...(Lines snipped)...

Notice that a password is requested; this is the user's password, not the root password.

The user can also execute ifconfig:

$ sudo /sbin/ifconfig eth2 down

The full pathname of the command (/sbin/ifconfig) is required because /sbin is not in the user's normal search path.

It is reasonable idea to add /sbin and /usr/sbin to everyone's search path, since it makes both sudo and su more useful and provides easy access to the nonprivileged modes of the administration utilities.

This time, no password is requested because it's been less than five minutes since the last time sudo asked for the user's password. To disable the password request entirely, add the keyword NOPASSWD: after the equal sign in the sudoers entry:

chris ALL=NOPASSWD:/bin/netstat,/sbin/ifconfig

By default, sudo enables the execution of the listed commands as root; to enable execution as another user, place that user's name in parentheses after the equal sign in the configuration entry. For example, to permit chris to run the script /usr/local/bin/checkstatus as the user scott:

chris ALL=(scott) NOPASSWD:/usr/local/bin/checkstatus

chris can then use sudo with the -u option to specify the desired user ID:

$ sudo -u scott checkstatus

Replacing the command list with the word ALL will include all commands. For example, this entry permits chris to execute any command or script as root:

chris ALL=ALL

Permitting unrestricted access to all commands through sudo is equivalent to giving away the root password. A root user can compromise the system at very basic levels, making it impossible to later secure the system, even if you cut off that user's access.

For convenience, you can define groups of users, hosts, or commands and then reference those in entries. This is done by using the User_Alias, Host_Alias, and Cmnd_Alias statements.

For example, to define a group of administrators and permit them to run the ifconfig and route commands as root on any of a group of desktop systems, you could use a configuration file like this:

User_Alias  ADMINS=sally,harry,jason
Cmnd_Alias  NETCONFIG=ifconfig,route


8.5.2. How Does It Work?

The sudo program executes with root privilege. If you view the permissions on the binary, you will see that the set-user-ID permission bit is enabled (note the s in the user community permissions):

$ ls -l /usr/bin/sudo
---s--x--x 2 root root 106832 Feb 12 04:41 /usr/bin/sudo

Since this bit is set and the file is owned by root, it executes with root's privilege.

sudo checks the /sbin/sudoers file to determine if and how it should run the requested command. It requests a password if necessary, and then either denies execution or changes the effective user ID to the specified value (or leaves it as root) and executes the requested command.

When the user is prompted forand successfully entersher password, sudo updates a timestamp file in /var/run/sudo. The next time sudo is executed, the timestamp is checked, and if it is less than five minutes old, the user is not prompted for her password again. The timestamp is then updated.

The value of sudo lies in the ability to permit a user to execute specific commands with privilege. However, it's easy to accidentally misconfigure sudo to permit more access than intended.

For example, if you wish to permit frank to view text files owned by jenny, you could create the sudoers entry:

frank ALL=(jenny) NOPASSWD:/usr/bin/less

But the less command permits the user to access the shell by typing !, and frank can use this loophole to execute any command as though he were jenny:

frank$ sudo -u jenny less /home/jenny/.bash_profile
...(Normal output of less)...
$ id
uid=508(jenny) gid=508(jenny) groups=508(jenny) 
$ mail -s
Subject: I Quit I quit because you are a hateful, mean boss. -Jenny .
$ rm -rf /home/jenny/*
$ exit
...(Normal output of less)...

It can be useful to configure sudo for ALL commands for users that already have the root password because it encourages good practice, especially when used without the NOPASSWD option. The benefits of this configuration are:

  • A user can assume root privilege from time to time only when it is necessary, operating without root privilege the majority of the time. Compared to the use of a root shell, this practice reduces the likelihood that a command will accidentally be executed with privilege.

  • If the user steps away from the display while a shell is open, root access is not exposed.

  • The user must enter a password to escalate privilege but does not have to enter the password for each individual privileged command in a series.

  • The act of typing sudo in front of privileged commands serves to remind the user to check the command carefully.

8.5.3. What About... ...changing the password timeout?

By default, sudo won't prompt the user for their password as long as they have entered it successfully in the last five minutes. To change this value, add this entry to the top of the /etc/sudoers file:

Defaults timestamp_timeout=2

The value for this timeout is expressed in minutes. ...voluntarily giving up the password timestamp?

The user can voluntarily give up the timestamp at any time using the -k option:

$ sudo -k

This is useful if the terminal will be unattended for a while. ...disabling the root password entirely (like a Debian or Ubuntu system)?

The Fedora community has discussed this idea and ultimately opted to keep a root password. Fedora's consolehelper PAM configuration relies on a root password, and using a root password can in some cases provide one additional obstacle to gaining superuser access.

8.5.4. Where Can I Learn More?

  • The manpages for sudo, sudoers, and visudo

Previous Page
Next Page