sections in this module | City
College of San Francisco - CS260A Unix/Linux System Administration Module: Permitting Privileged Operations I |
module list |
sudo is a program that allows specific users to execute specific commands as other user(s), as indicated by the rules encoded in the sudoers file /etc/sudoers. Privileges about what can be done by whom can be granted with whatever granularity is desired. It is easy to encode capabilities such as these:
sudo is used by simply preceding the command that requires privileges with sudo:
sudo [ -u user ] command
Normally, sudo is used to execute a command as root. This is the default unless -u user is used to specify who to run the command as. By default, sudo will request a password. This is the password of the user running sudo, not of the user he or she wants to become. This ensures that the sudo user is actually the user who logged in (i.e., a guard against someone using your terminal when you step away)
You can inquire about your abilities to run commands using sudo by the command sudo -l A listing of the commands you can execute via sudo and who you can execute them as is output.
Plusses of sudo
Minuses of sudo
Overuse of sudo
Some linux systems, as installed, force the use of sudo to perform any operation as root, but allow any user to use it. The purpose of this is to limit root privileges to executing a single command at a time, and to log the commands that are executed. The true power of sudo is its ability to allow privileged operations on a user-by-user basis.
Warnings
sudo's task is to provide the privileges encoded in the sudoers file strictly. It has no idea what the commands do. It is only responsible for whether the user can execute them. Once the command has been started by sudo, the user can do whatever the command allows them to do.
For example, it would be easy to create a rule in sudo to let gboyd run the command bash as root. sudo is responsible for ensuring that only gboyd can run the command and that only bash can be run. It has no idea what gboyd can do with bash. Of course, gboyd now has a shell running as root and can do whatever he desires. Such a rule would be silly.
The issue is this: if a user is allowed to start a privileged process, he or she can do whatever the process can do. If the process starts child processes, the children inherit the privileges from their parent. You must therefore know exactly what a command is capable of before granting privileged access to it.
Each entry in the sudoers file specifies
user hosts = [ (runas) ] [ NOPASSWD: | PASSWD: ] [NOEXEC:] cmd
Each field (user, hosts, runas, cmd) can be a single item or a comma-separated list of items. Each can also be a sudo alias, as explained later. We will discuss the format of each of these parts of the sudo command in its own section following.
The optional keywords NOPASSWD: or PASSWD: govern whether the user will be required to enter his or her user password before executing the command. PASSWD: is the default. The NOEXEC: keyword, if specified, will try to run the command with a patch that will cause the exec() system call to fail. This should effectively suppress shell escapes. Note: the NOEXEC: keyword will only work on native dynamically-linked executables on systems that support LD_PRELOAD, such as Linux.
In each field, the keyword ALL can be substituted to indicate "all possible". Thus,
ALL ALL = (ALL) NOPASSWD: ALL
This rule is used to simply log all actions of root, and is used by the system owner, who is not given a root password. It thus substitutes for logging in as root and provides an accounting trail. This rule appears on current versions of Mac OSX and Ubuntu linux, with the exception that the users who execute it may be limited to those who are members of a particular group, such as admin:
%admin ALL = (ALL) NOPASSWD: ALL
The sudoers file is divided into sections, in this order:
user hosts = [ (runas) ] [ NOPASSWD: | PASSWD: ] cmd
Alias names
Aliases associate a name with a list of possibilities, as discussed below. Alias names may contain uppercase letters, numbers, and the underscore. They must begin with a letter, and may NOT contain any lowercase letters.
Specification of user and runas
The user field can be a comma-separated list of users, uids, User_Aliases, and groups. Groups are indicated by the prefix %. An individual user may also be specified by their uid prefixed by #, and may be negated by a prefix of !. Thus, if the user field is
gboyd,OPERATORS,!randy,%sys,#0
and OPERATORS is a User_Alias, the sudo command may be run by the individual user gboyd, any of the users indicated in the User_Alias OPERATORS, any member of the group sys, the user with uid 0, but not by randy.
A User_Alias associates the alias name with a comma-separated list of users, in the same format as above. Thus, we could create a User_Alias named SYS to include the users above like this:
User_Alias SYS = gboyd,OPERATORS,!randy,%sys,#0
Note that a User_Alias can include another User_Alias. (I assume OPERATORS must be defined before SYS.)
The runas field has the same syntax as the user field, and uses User_Aliases.
Specification of hosts
As mentioned previously, we will not discuss this field, nor its aliases. Instead, we will use the placeholder ALL to indicate "all applicable hosts".
Specification of cmd
The cmd field can be a comma-separated list of commands and Cmnd_Aliases. Each command can be one of these formats:
Thus, if the cmd field is
/bin/ls, /bin/cat /var/log/messages, /sbin/sudocmds, /sbin/shutdown -h now, SYS_CMDS
where SYS_CMDS is a Cmnd_Alias and /sbin/sudocmds is a directory, the following commands may be run:
A Cmnd_Alias associates the alias name with a comma-separated list of commands, in the same format as above. Thus, we could create a Cmnd_Alias named MY_CMDS to include a few commands like this:
Cmnd_Alias MY_CMDS = /bin/ls, /bin/cat /var/log/messages, /sbin/shutdown -h now
Again, a Cmnd_Alias can include another Cmnd_Alias
Examples
Consider the sudo line
gboyd ALL=(root) /usr/local/bin/doit ""
This allows gboyd to run the command /usr/local/bin/doit as root, so long as he does not try to give the command any arguments. It also does not allow him to run the command as anyone else (other than root). Note that if doit is in gboyd's PATH, he does not need to indicate the absolute path. (In other words, if, when gboyd executes the command doit, doit is resolved to /usr/local/bin/doit, gboyd can use sudo to execute doit.)
The sudo line
allows the user student to copy anything she wants to /usr/local/bin as any other user. An attempt to copy anywhere else fails.
The sudo line
allows all members of the group users except gboyd to execute the /usr/local/bin/upd command, so long as they don't specify arguments. They do not need to enter their password when they run the command, but they can only run the command as the user bin. Thus, unless they use the -u bin option to sudo, permission will be denied (as without -u bin, sudo will attempt to run the command as root).
The last sudo lines
gboyd,francis,susan,jamal,alfonzo,tarzan ALL= /sbin/shutdown -h *
gboyd,francis,susan,jamal,alfonzo,tarzan ALL= /sbin/shutdown -r *
allows all of these users to execute the shutdown command, so long as either the -r or -h option is used. The wildcard at the end of the command allows the user to provide a shutdown message This last set of commands could be simplified using aliases:
User_Alias OPERATORS = gboyd,francis,susan,jamal,alfonzo,tarzan
Cmnd_Alias SHUTDOWN = /sbin/shutdown -h *, /sbin/shutdown -r *
OPERATORS ALL = SHUTDOWN
There are several sources of errors when you are writing entries for the sudoers file
A final warning
Make sure that any command you allow to run under sudo does not allow a shell escape. Remember, sudo is only responsible for starting the command. It has no control over what the command does.
For example, a simple task to put under the control of sudo would be to allow others to review the system messages log file. Thus, a tempting sudo entry would be
ALL ALL= /bin/more /var/log/messages
If the user then ran sudo to use more on the messages file as root, the first page of the log file would be displayed:
When a shell escape is used at the more prompt, the result is to start a new shell as root!Feb
24 10:09:41 lenny dhclient: DHCPREQUEST on eth0 to 147.144.23.30
port 67
Feb 24 10:09:41 lenny
dhclient: DHCPACK from 147.144.23.30
Feb 24 10:09:41 lenny
dhclient: bound to 147.144.23.57 -- renewal in 8713 seconds.
!bash
bash-3.00# id
uid=0(root) gid=0(root)
groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
context=root:system_r:unconfined_t
bash-3.00#
Thus, our seemingly harmless sudo line has given everyone access to the root account.
This problem is easy to remedy. The foolproof way is to know which programs allow shell escapes, and simply replace the entry with a different, safer tool. In our example, use
Then users can simply send the output of cat to more. The more process is not initiated by sudo, thus it is not privileged:
sudo cat /var/log/messages | more
The more elegant solution simply adds the NOEXEC: keyword to the command, as follows:
ALL ALL= NOEXEC: /bin/more /var/log/messages
Now when a shell escape is attempted, it fails.
As discussed earlier, there are some limitations on the effectiveness of NOEXEC:, and sudo can't easily determine this. If you have any questions about whether it will work on your system, just avoid giving sudo access to programs that have a shell escape.
Prev | This page was made entirely
with free software on linux: the Mozilla Project and Openoffice.org |
Next |