ONLamp.com    
 Published on ONLamp.com (http://www.onlamp.com/)
 See this if you're having trouble printing code examples


Big Scary Daemons Sudo Aliases and Exclusions

by Michael W. Lucas
09/12/2002

Last time, we looked at the basic sudo(8) setup. The hardest part of using sudo is configuring its permissions file, sudoers. As you can imagine, once you have several different machines with multiple administrators all with different levels of privilege, sudoers quickly gets very complicated. Aliases can simplify sudo maintenance and greatly clean up your sudo configuration.

Basically, an alias is a group of users, hosts, or commands. When a user's duties change, you can just add them to the appropriate user alias to give them correct sudo privileges. If you want your system operators to be able to back up the system, but no longer restore data, you can remove the restore commands from their command alias. When you install a new server, adding the server name to the proper alias will allow you to instantly give system administrators the proper permissions to do their jobs.

An alias must be defined before it can appear in the sudoers file. For that reason, aliases generally appear at the top of the file. Each alias entry has a label saying what sort of alias it is, a label for the alias, and a list of the members of that alias.

User aliases are groups of users, and are labeled with the string User_Alias. They contain a list of users that are in that alias.

User_Alias   DNSADMINS = chris,mwlucas

The user alias DNSADMINS contains two users, mwlucas and chris.

A Runas alias is a special type of user alias. This lists users that other users can run commands as. Many nameservers can be run as the user "named." The DNS administrator might need to be able to run commands as that user, and you might have a Runas alias for that. Many database applications run as their own special user. In many cases, a system administrator responsible for an application would also want to be able to run system backups as the user "operator." Or, you could just create a single Runas alias to group these commands. Runas aliases are labeled with Runas_Alias.

Runas_Alias   APPADMIN = named,dbuser,operator

A host alias is just a list of hosts. They're labeled with the string Host_Alias. A host alias can be defined in terms of hostnames, IP addresses, or network blocks. (Remember, if you're using hostnames your sudo configuration could be vulnerable to DNS problems!) Here are examples of all three.

Host_Alias   DNSSERVERS = dns1,dns2,dns3
Host_Alias   SECURITYSERVERS = 192.168.1.254,192.168.113.254
Host_Alias   COMPANYNETWORK = 192.168.1.0/16

A command alias is a list of commands. They're labeled with the string Cmnd_Alias. Here, we have an alias that includes all the commands necessary to back up to tape, or restore the system from backup.

Cmnd_Alias   BACKUPS = /bin/mt,/sbin/restore,/sbin/dump

You might have a command alias that includes all the commands in a particular directory. Suppose we have a custom application that runs as a particular user, and places all of its commands in the app users' home directory. Rather than list all the commands, can just list directory and use a wildcard to include everything in the directory.

Cmnd_Alias   DBCOMMANDS = /usr/home/dbuser/bin/*

To use an alias, just put the alias name in the rule where you would normally list the user, command, or hostname. We've previously defined a user alias DNSADMINS. The users listed in the DNSADMINS alias get to run any commands at all on all of our servers.

DNSADMINS   ALL = ALL

Let's suppose that our user Phil has to manage an application that runs as a particular user. He can run any command on the system as this application user. We defined a Runas alias in the last section for the user alias APPADMIN, and an alias for commands needed to run the application, DBCOMMANDS.

phil   ALL = (APPADMIN)DBCOMMANDS

As the application administrator, Phil might also have to run backups. We have already given the APPOWNER Runas alias operator privileges, and we have a separate command alias for backup commands. We can combine them all like this.

phil   ALL = (APPOWNER) DBCOMMANDS, (APPOWNER)BACKUPS

This is much simpler to read than what this rule expands to.

phil   ALL = (dbuser,operator)/usr/home/dbuser/bin/*,\
     (dbuser,operator)/bin/mt, (dbuser,operator)/sbin/restore,\
     (dbuser,operator)/sbin/dump

Some of the permissions granted by sudo in this case are unnecessary -- having the database user Runas alias is not necessary for running backups. Still, it's far tighter than just giving Phil the root password! You can also define rules to restrict your users as tightly as you desire.

You can include aliases in aliases. For example, you could group the DBCOMMANDS alias and the BACKUPS commands into a single group of commands. The included aliases must be defined before they're used.

Cmnd_Alias   DBADMINS = BACKUPS,DBCOMMANDS

sudo can pull group information from the system, and incorporate it into sudoers as a user alias. Rather than explicitly define a user alias, you can give the system group name preceded by a percent sign (%) to indicate it's a group name.

%wheel   ALL = ALL

Anyone in the system's wheel group can issue any command as root, on any server.

Duplicating Alias Names

You can reuse alias names. The user alias DBADMINS is not the same as the DBADMINS command alias. It's quite possible to have sudoer entries like this.

Cmnd_Alias   DBAPP = /usr/home/dbuser/bin/*
Host_Alias   DBAPP = server8,server12,server15
RunasAlias   DBAPP = dbuser,operator
User_Alias   DBAPP = chris,mwlucas
DBAPP        DBAPP = (DBAPP) DBAPP

This is an excellent example of "technically correct, but morally unacceptable." If you do this, anyone who has to debug your sudo configuration will curse your name at great length. On the down side, things like this tend to result in phone calls during the middle of whatever scant hours the senior system administrator is permitted to sleep in.

Essential System Administration

Related Reading

Essential System Administration
Tools and Techniques for Linux and Unix Administration
By Æleen Frisch

Now, let's check out a common situation that trips up even experienced systems administrators. Sometimes you want to disallow users from executing certain commands, but give them access to every other command. You can try to do this with the "!" operator, but it's not entirely effective. Since it's a popular setup, however, we'll discuss how this works and then what's wrong with it.

First, define command aliases that contain the forbidden commands. Popular commands to exclude are shells (if you execute a shell as a user, you become that user) and su(1). Then give your user a command rule that excludes those aliases with the ! operator.

Cmnd_Alias   SHELLS = /bin/sh,/bin/csh,/usr/local/bin/tcsh
Cmnd_Alias   SU = /usr/bin/su
mwlucas      ALL = ALL,!SHELLS,!SU

Looks great, doesn't it? And it seems to work.

# sudo sh
Password:
Sorry, user mwlucas is not allowed to execute '/bin/sh' as root on openbsd.
#

Remember, sudo uses full paths for all the commands. You're allowing the user to run any command they want, except for a few that are specified by their full path. All that user needs to do is change their path to one of these commands to run it! The easiest way to do this is by copying the command to another location.

# id
uid=1000(mwlucas) gid=1000(mwlucas) groups=1000(mwlucas), 0(wheel)
# cp /bin/sh .
# sudo ./sh 
# id
uid=0(root) gid=0(wheel) groups=0(wheel), 2(kmem), 3(sys), 
                  4(tty), 5(operator), 20(staff), 31(guest)
# 

Hello, root!

This sort of restriction can be bypassed trivially, by anyone who understands even the basics of how sudo works. This problem is well-documented in the sudo manual and the other literature. And people still insist upon using it to protect production systems!

If you have users that you do not trust with unrestricted access to the system, do not exclude commands from their sudo permissions. Instead, explicitly list the commands that they may use, and leave it at that. This exclusion can be useful with trusted users (i.e., employees), but only as an advisory. More than once I've logged onto a system and typed "sudo su", only to have sudo remind me that I am not supposed to do that on this system.

This concludes our tour of sudo. You can learn much more about sudo by reading sudo(8), sudoers(5), and the sudo Web page.

Michael W. Lucas


Read more Big Scary Daemons columns.

Return to the BSD DevCenter.


Copyright © 2009 O'Reilly Media, Inc.