Путеводитель по Руководству Linux

  User  |  Syst  |  Libr  |  Device  |  Files  |  Other  |  Admin  |  Head  |



   sudoers    ( 5 )

плагин политики безопасности sudo по умолчанию (default sudo security policy plugin)

Безопасность (Security)

Limitations of the '!' operator It is generally not effective to 'subtract' commands from ALL using the '!' operator. A user can trivially circumvent this by copying the desired command to a different name and then executing that. For example:

bill ALL = ALL, !SU, !SHELLS

Doesn't really prevent bill from running the commands listed in SU or SHELLS since he can simply copy those commands to a different name, or use a shell escape from an editor or other program. Therefore, these kind of restrictions should be considered advisory at best (and reinforced by policy).

In general, if a user has sudo ALL there is nothing to prevent them from creating their own program that gives them a root shell (or making their own copy of a shell) regardless of any '!' elements in the user specification.

Security implications of fast_glob If the fast_glob option is in use, it is not possible to reliably negate commands where the path name includes globbing (aka wildcard) characters. This is because the C library's fnmatch(3) function cannot resolve relative paths. While this is typically only an inconvenience for rules that grant privileges, it can result in a security issue for rules that subtract or revoke privileges.

For example, given the following sudoers file entry:

john ALL = /usr/bin/passwd [a-zA-Z0-9]*, /usr/bin/chsh [a-zA-Z0-9]*,\ /usr/bin/chfn [a-zA-Z0-9]*, !/usr/bin/* root

User john can still run /usr/bin/passwd root if fast_glob is enabled by changing to /usr/bin and running ./passwd root instead.

Preventing shell escapes Once sudo executes a program, that program is free to do whatever it pleases, including run other programs. This can be a security issue since it is not uncommon for a program to allow shell escapes, which lets a user bypass sudo's access control and logging. Common programs that permit shell escapes include shells (obviously), editors, paginators, mail and terminal programs.

There are four basic approaches to this problem:

restrict Avoid giving users access to commands that allow the user to run arbitrary commands. Many editors have a restricted mode where shell escapes are disabled, though sudoedit is a better solution to running editors via sudo. Due to the large number of programs that offer shell escapes, restricting users to the set of programs that do not is often unworkable.

intercept Many systems that support shared libraries have the ability to override default library functions by pointing an environment variable (usually LD_PRELOAD) to an alternate shared library. On such systems, sudo's intercept functionality can be used to transparently intercept an attempt to run a new command, allow or deny it based on sudoers rules, and log the result. For example, this can be used to restrict the commands run from within a privileged shell. Note, however, that this applies only to dynamically-linked executables. Statically-linked executables and executables running under binary emulation are not affected. Also, most shells support built-in commands and the ability to read or write sensitive files that cannot be intercepted by sudo.

Currently, sudo's intercept functionality only works for programs that use the execve() system call to run the new command. This may be expanded in a future release of sudo. Because most dynamic loaders ignore LD_PRELOAD (or the equivalent) when running set-user-ID and set-group-ID programs, sudoers will not permit such programs to be run in intercept mode.

The intercept feature is known to work on Solaris, *BSD, Linux, macOS, HP-UX 11.x and AIX 5.3 and above. It should be supported on most operating systems that support the LD_PRELOAD environment variable. Check your operating system's manual pages for the dynamic linker (usually ld.so, ld.so.1, dyld, dld.sl, rld, or loader) to see if LD_PRELOAD is supported.

To enable intercept mode on a per-command basis, use the INTERCEPT tag as documented in the User Specification section above. Here is that example again:

chuck research = INTERCEPT: ALL

This allows user chuck to run any command on the machine 'research' in intercept mode. Any commands run via shell escapes will be validated and logged by sudo. If you are unsure whether or not your system is capable of supporting intercept, you can always just try it out and check whether or not external commands run via a shell are logged when intercept is enabled.

log There are two separate but related ways to log additional commands. The first is to enable I/O logging using the log_output flag. This will log the command's output but will not create an event log entry when the additional command is run. The second is to enable the log_children flag in sudoers which will create an event log entry every time a new command is run. If I/O logging is also enabled, the log entry will include a time offset into the I/O log to indicate when the command was run. This offset can be passed to the sudoreplay(8) utility to replay the I/O log at the exact moment when the command was run. The log_children flag uses the same mechanism as intercept (see above) and has the same limitations.

noexec sudo's noexec functionality can be used to prevent a program run by sudo from executing any other programs. On most systems, it uses the same mechanism as intercept (see above) and thus the same caveats apply. The noexec functionality is capable of blocking execution of commands run via the execl(), execle(), execlp(), exect(), execv(), execve(), execveat(), execvP(), execvp(), execvpe(), fexecve(), popen(), posix_spawn(), posix_spawnp(), system(), and wordexp() functions. On Linux, a seccomp() filter is used to implement noexec. On Solaris 10 and higher, noexec uses Solaris privileges instead of the LD_PRELOAD environment variable.

To enable noexec for a command, use the NOEXEC tag as documented in the User Specification section above. Here is that example again:

aaron shanty = NOEXEC: /usr/bin/more, /usr/bin/vi

This allows user aaron to run /usr/bin/more and /usr/bin/vi with noexec enabled. This will prevent those two commands from executing other commands (such as a shell). If you are unsure whether or not your system is capable of supporting noexec you can always just try it out and check whether shell escapes work when noexec is enabled.

Note that restricting shell escapes is not a panacea. Programs running as root are still capable of many potentially hazardous operations (such as changing or overwriting files) that could lead to unintended privilege escalation. In the specific case of an editor, a safer approach is to give the user permission to run sudoedit (see below).

Secure editing The sudoers plugin includes sudoedit support which allows users to securely edit files with the editor of their choice. As sudoedit is a built-in command, it must be specified in the sudoers file without a leading path. However, it may take command line arguments just as a normal command does. Wildcards used in sudoedit command line arguments are expected to be path names, so a forward slash ('/') will not be matched by a wildcard.

Unlike other sudo commands, the editor is run with the permissions of the invoking user and with the environment unmodified. More information may be found in the description of the -e option in sudo(8).

For example, to allow user operator to edit the 'message of the day' file:

operator sudoedit /etc/motd

The operator user then runs sudoedit as follows:

$ sudoedit /etc/motd

The editor will run as the operator user, not root, on a temporary copy of /etc/motd. After the file has been edited, /etc/motd will be updated with the contents of the temporary copy.

Users should never be granted sudoedit permission to edit a file that resides in a directory the user has write access to, either directly or via a wildcard. If the user has write access to the directory it is possible to replace the legitimate file with a link to another file, allowing the editing of arbitrary files. To prevent this, starting with version 1.8.16, symbolic links will not be followed in writable directories and sudoedit will refuse to edit a file located in a writable directory unless the sudoedit_checkdir option has been disabled or the invoking user is root. Additionally, in version 1.8.15 and higher, sudoedit will refuse to open a symbolic link unless either the sudoedit_follow option is enabled or the sudoedit command is prefixed with the FOLLOW tag in the sudoers file.

Time stamp file checks sudoers will check the ownership of its time stamp directory (/run/sudo/ts by default) and ignore the directory's contents if it is not owned by root or if it is writable by a user other than root. Older versions of sudo stored time stamp files in /tmp; this is no longer recommended as it may be possible for a user to create the time stamp themselves on systems that allow unprivileged users to change the ownership of files they create.

While the time stamp directory should be cleared at reboot time, not all systems contain a /run or /var/run directory. To avoid potential problems, sudoers will ignore time stamp files that date from before the machine booted on systems where the boot time is available.

Some systems with graphical desktop environments allow unprivileged users to change the system clock. Since sudoers relies on the system clock for time stamp validation, it may be possible on such systems for a user to run sudo for longer than timestamp_timeout by setting the clock back. To combat this, sudoers uses a monotonic clock (which never moves backwards) for its time stamps if the system supports it.

sudoers will not honor time stamps set far in the future. Time stamps with a date greater than current_time + 2 * TIMEOUT will be ignored and sudoers will log and complain.

If the timestamp_type option is set to 'tty', the time stamp record includes the device number of the terminal the user authenticated with. This provides per-terminal granularity but time stamp records may still outlive the user's session.

Unless the timestamp_type option is set to 'global', the time stamp record also includes the session ID of the process that last authenticated. This prevents processes in different terminal sessions from using the same time stamp record. On systems where a process's start time can be queried, the start time of the session leader is recorded in the time stamp record. If no terminal is present or the timestamp_type option is set to 'ppid', the start time of the parent process is used instead. In most cases this will prevent a time stamp record from being re-used without the user entering a password when logging out and back in again.