Security is an important part of your system, whether it’s a home stand-alone machine or a networked server. After functionality, security should be your primary concern when considering your computer. If you don't have a secure system, your important data is up for grabs.
With Linux, this is especially true. Lately, a slew of security problems have come to light, and vendors have been releasing updates for problematic programs like there was no tomorrow. This latest wave of updates is due primarily to buffer overflows, string format vulnerabilities, and insecure use of the file system. While we are not going to discuss these things in this Daily Drill Down, they serve to illustrate one simple point: Security is important! Keeping up to date on vendor updates is an important step. By keeping abreast of new problems, you can quickly update them and close any open holes in your system.
It's also important to keep a healthy balance of usability and security on your system. Too much security makes your system difficult for you or others to use. So how do you know what is enough and what isn't? Quite frankly, only you can make that call. No one can tell you how restrictive to make your system. You may tighten all the hatches just to find that your users can't use the system. You may have to relax things a little bit to get that necessary level of usability back in your system. And that is all right. There is no point in locking your system so tight that you can't use it.
In this Daily Drill Down we're going to look at an exceptional tool that will make your life as an administrator of a Linux system a lot simpler. We all know the importance of the root user. We also know that there are some things that other users may need to do that only root can do. Let's take a look at a tool that will help us accomplish this while keeping a secure system.
Everyone using Linux should know that the root password must be guarded religiously. To hand out your root password to anyone is taboo. While you can prevent your system from allowing remote logins as root, you may still see the need to use a program called su that allows you to change to the user root once you have logged into the system as a user. Many people use su to do things like reboot the computer and run other administrative tools.
While this is acceptable, it shouldn't be encouraged. For instance, if you telnet into a machine, you are transmitting information in the clear. If you then su to root, you will be transmitting your root password in the clear so anyone who may be paying attention can grab it. You've then compromised your system. By using ssh, you can reduce this threat to a point of near nonexistence.
Then you may need to make a decision. If someone other than the administrator needs to shut down the system, do you give him or her the root password to reboot the machine? Absolutely not! So how then, if they cannot su to root, do they reboot the machine or perform any other administrative task?
The simple answer is sudo, which stands for "superuser do." It allows the system administrator to give certain users and groups the ability to run some or all of the commands that only root can run. At the same time, sudo logs all of the given commands and arguments so the administrator can examine them at any time.
This provides you with two very important things. The first is user accountability. Anyone using sudo is automatically logged. By perusing the sudo log file, you can see who did what and when. You can also see whether or not they were monkeying around where they shouldn't have been. The next important thing it provides is flexibility for the user without compromising system security. For instance, you can allow user joe access to reboot the machine without giving him the root password or allowing him to do any other administrative "as root" functions.
Sudo is not a new tool and comes with most Linux distributions. Check to see whether sudo is already installed. If not, it most likely will be on the distribution CD, and you can install it from there. Most people are more used to and comfortable with su, however, which means they need a little reprogramming. Being human, we are inherently lazy. I often find myself using su in an xterm and just leaving the window open. Anyone can then come to my computer and if I haven't secured my desktop, easily roam my system as root. In that case, they don't need the root password. I've just given them free rein to my machine by using su. Using sudo will eliminate this.
Sudo is pretty easy to configure. It has one main configuration file called /etc/sudoers. This file should be readable by root only. Ensure that the permissions on the file are 440. This means that the user (root) and group (root) have read permission to this file.
To edit this file, you must use the tool visudo. Unfortunately, this means you need to have a basic understanding of the vi editor in order to edit the file. If you feel ambitious or you really can't stand vi, you can rebuild sudo and give it a special configuration option which will read the EDITOR environment variable and use the editor found, or default to vi. For instance, when building sudo you would use:
This means that you can run the following command to edit the /etc/sudoers file with the joe editor:
export EDITOR=joe; visudo
Now you can edit the file using joe. The /etc/sudoers file is basically split into two sections: aliases and user specifications. Let's take a look at a basic /etc/sudoers file:
# User alias specifications
User_Alias WEBMASTERS = bob, joe
# Command alias specifications
Cmnd_Alias SHUTDOWN = /usr/sbin/shutdown
Cmnd_Alias WEBINIT = /etc/rc.d/init.d/httpd
# User specifications
# root and users in group wheel can run anything as any user
root ALL = (ALL) ALL
%wheel ALL = (ALL) ALL
# webmasters can restart apache as well as run any command as user
# apache (which owns the web pages) or simply su to user apache
WEBMASTERS ALL = WEBINIT, apache = (apache) ALL, (root) /usr/bin/su apache
# joe can also shutdown the machine
joe ALL = SHUTDOWN
This is a very simple sudoers file, which defines a few things. The first thing we do is create a group called WEBMASTERS, which includes the users bob and joe. Then, we define two command aliases. The first, SHUTDOWN, is an alias to the shutdown command. The second, WEBINIT, is an alias to the command used to restart Apache.
We then define some user specifications. The first defines that the root user can do anything as any user. The second defines that all members of the group wheel (groups are written with a percent sign in front of them, like %wheel) can also run anything as any user.
Next, the members of the WEBMASTERS group are given access to run the WEBINIT alias command. They are also allowed to run any command as the user apache (which is fairly limited since the user apache is what Apache changes to once it starts). Also, they are allowed to su to the user apache. When they run the su command to apache, they run su as root so they are not prompted for a password.
Finally, user joe is permitted to run the SHUTDOWN alias command so he can shut down the computer.
You can get very complicated with the sudoers file. It was designed to be used across networks so you can also define computers in the file and permit users to do certain things on certain hosts alone.
Syntax of sudoers
The syntax of the sudoers file is not straightforward, but with a little help it can be easily understood. The file uses aliases for nearly everything, and there are four types of aliases: User_Alias, Runas_Alias, Host_Alias, and Cmnd_Alias. The syntax for each alias is:
User_Alias NAME = User_List
Runas_Alias NAME = Runas_User_List
Host_Alias NAME = Host_List
Cmnd_Alias NAME = Cmnd_List
where each respective list can be one or more items separated by a comma like this:
User_Alias NAME = user1, user2, ...
The NAME can be any case, but the first letter must be uppercase. You can also use numbers and the underscore character in the NAME. You can include several alias definitions on a single line by using a semicolon to separate them, like this:
User_Alias NAME = user1, user2 ; NAME = user3, user4, ...
The User_Alias alias
The User_Alias alias defines a list of usernames, uids, system groups, netgroups, and other aliases. The username can be specified as normal, for example "joe" is a valid username. Uids must be prefixed with a "#" symbol, for example, "#502" would be valid to specify uid 502. System groups must be prefixed with a "%" symbol, for example, "%wheel" would be valid to specify the group wheel. Netgroups must be prefixed by a "+" symbol, for example, "+mygroup" would be valid to specify the netgroup mygroup. Finally, you may also use the "!" symbol to exclude an item. For example, specifying "%users !joe" would be equivalent to specifying "all members of group users except user joe."
The Runas_Alias alias
The Runas_Alias alias is similar to the User_Alias in convention. You can specify usernames, uids, system groups, netgroups, and excluded items the same way you would with the User_Alias. This alias is used to define users that belong to an alias. For instance:
Runas_Alias DB = mysql
Runas_Alias OP = root, operator
This means that anyone given access to the OP alias may run commands as the user root or operator while anyone given access to the DB alias may run commands as the user mysql.
The Host_Alias alias
The Host_Alias alias defines a list of hostnames, IP addresses, network numbers, netgroups, and other aliases. All items are written as normal, but the netgroup must be prefixed with the "+" symbol, similar to the User_Alias and Runas_Alias aliases. You can specify a netmask along with the IP address in the form "ip/netmask" or, for example, "192.168.1.1/255.255.255.0." If you omit the netmask, the netmask of the host's Ethernet interface will be used when doing matching. You can also use the number of bits instead of the full netmask (CIDR notation), so instead of writing the IP address as "192.168.1.1/255.255.255.0" you could write it as "192.168.1.1/24."
The Cmnd_Alias alias
The Cmnd_Alias defines a list of command names, directories, and other aliases. The command name must be a fully qualified filename, which may also contain shell-style wildcards. If you specify the filename alone, the user will be able to append arguments to the command. You can use command-line arguments as well by writing the command as you wish it to be run. Finally, if you enclose the command in quotes, the user will not be able to run it with command-line arguments (allowing you to limit sudo access to a required program that may have insecure or potentially damaging command-line arguments). You can also specify directories, allowing the user to run any programs contained in the directory but not in any subdirectories unless authorization is explicitly granted to that subdirectory as well. To specify a directory, simply write the full path to the directory and add a forward slash ("/") at the end.
The Defaults command
You can also use sudo to specify some defaults on how it will operate. We will look at a few of the useful defaults, but looking at the sudoers man page will provide you with a full list of options. To view the man page, execute:
The syntax for the Defaults command is:
Let's take a look at some examples:
Defaults@SERVERS log_host, log_year
Default:WEBMASTERS insults, logfile=/var/log/sudoweb.log
This means that by default, the syslog facility used will be "auth," which is where most login information is stored by syslog. For all hosts in the Host_Alias SERVERS we will log the hostname sudo has called on, as well as a four-digit year. When sudo is called by anyone in the User_Alias WEBMASTERS, we will insult them if they provide an incorrect password and log everything to the file /var/log/sudoweb.log.
A few other caveats to the /etc/sudoers file exist. You can use a "#" symbol at the beginning of the line to indicate a comment. You can continue long commands across multiple lines by ending the line to be continued with the "\" character. The magic word ALL means everything goes. It can mean all commands or all machines in the network.
Let's take a look at a few more useful examples:
User_Alias MYUSERS = jim, joe
MYUSERS ALL = NOPASSWD: ALL
This sets up the User_Alias MYUSERS, which includes the users jim and joe. We then define that the members of MYUSERS can use all commands on any hosts without needing to authenticate themselves. If we wanted to make jim and joe authenticate themselves before using any sudo commands, we would instead use:
MYUSERS ALL = ALL
Here is another useful example:
Cathy TITAN = ALL : LINUX = (DB) ALL : MYNET (ALL) ALL
This is an interesting one. Here, the user cathy has access to all commands on the machines in the Host_Alias TITAN. She likewise has access to all commands on the machines in the Host_Alias LINUX as any user listed in the DB Runas_Alias. Finally, on the machines specified in the MYNET Host_Alias, she can run all commands as any user she likes.
As you can see, sudo is an impressive piece of software with a lot of flexibility. The benefits of using sudo instead of su should be fairly obvious, both in terms of security and usability. Sudo offers a nice mix of both by allowing us such incredible versatility.
Using sudo, you can provide privileged commands to the people who need them and keep the system secure. You do not need to provide your root password to people who do not need it, nor do you need to do administrative tasks that someone else should be doing. As we've illustrated, you can include a few people who deal with the day-to-day business of maintaining a Web site and give them the ability to edit configuration files for Apache, restart Apache, and so forth. You can do this without giving them the ability to restart your FTP server or edit your /etc/passwd file as well, which would pose a security risk. And by using some judicious logging, you can keep track of which users use sudo to accomplish which tasks.
Security is important, there is no question about it. Education is important, as well. Most administrators are familiar with and use the su command, and many use it in an insecure manner. I am guilty of this as well, but making myself aware of the power of sudo and what it can do for me and, more importantly, what security and peace of mind it offers over su, I'm hooked. I can honestly say that I will be su'ing to root very seldom in the future and making more use of sudo.
If the particular distribution you use does not contain sudo, I encourage you to write to the vendor and ask them to include this tool. No Linux system should be without it. For more information on sudo, refer to the man pages or the official sudo Web site.
The authors and editors have taken care in preparation of the content contained herein but make no expressed or implied warranty of any kind and assume no responsibility for errors or omissions. No liability is assumed for any damages. Always have a verified backup before making any changes.
Vincent Danen works on the Red Hat Security Response Team and lives in Canada. He has been writing about and developing on Linux for over 10 years and is a veteran Mac user.