2 sudo
基础知识 #
运行某些命令需要 root 特权。但是,出于安全考虑以及为了避免出错,我们不建议以 root
身份登录。更安全的做法是先以普通用户身份登录,再使用 sudo
以提升的特权来运行命令。
在 SUSE Linux Enterprise Server 上,sudo
配置为与 su
的工作方式类似。但是,sudo
提供了一种灵活机制,可让用户使用其他任何用户的特权运行命令。这样,便可为某些用户和组指派具有特定特权的角色。例如,可以允许组 users
的成员使用用户 wilber
的特权运行命令。您可以通过禁止任何命令选项,来进一步限制对命令的访问。虽然 su 始终需要 root
口令才能使用 PAM 进行身份验证,但是您可以将 sudo
配置为使用您自己的身份凭证进行身份验证。这意味着用户无需共享 root
口令,因而提高了安全性。
2.1 sudo
基本用法 #
以下章节将会介绍 sudo
的基本用法。
2.1.1 运行单个命令 #
作为普通的用户,您可以在命令前加上 sudo
来以 root
身份运行任何命令。系统会提示您提供 root 口令。如果身份验证成功,便会以 root
身份运行命令:
>
id -un
1 tux>
sudo
id -un
root's password:2 root>
id -un
tux3>
sudo
id -un
4 root
| |
在输入过程中不会显示口令,无论是明文还是屏蔽字符都不显示。 | |
只有以 | |
提升的特权会持续一段时间,因此您不必再次提供 |
使用 sudo
时,I/O 重定向不起作用:
>
sudo
echo s > /proc/sysrq-trigger bash: /proc/sysrq-trigger: Permission denied>
sudo
cat < /proc/1/maps bash: /proc/1/maps: Permission denied
在上面的示例中,只有 echo
和 cat
命令才以提升的特权运行。重定向将由用户的外壳以用户特权执行。要以提升的特权执行重定向,请根据第 2.1.2 节 “启动外壳”中所述启动外壳,或使用 dd
实用程序:
echo s | sudo dd of=/proc/sysrq-trigger sudo dd if=/proc/1/maps | cat
2.1.2 启动外壳 #
使用 sudo
来以提升的特权运行命令的做法并不总是可行。虽然可以使用 sudo
bash
命令,但还是建议您使用以下其中一种内置机制来启动外壳:
sudo -s (<command>)
启动
SHELL
环境变量所指定的外壳或目标用户的默认外壳。如果指定了某个命令,该命令会传递到外壳(使用-c
选项)。否则,外壳将以交互模式运行。tux:~ >
sudo -s root's password:root:/home/tux #
exittux:~ >
sudo -i (<command>)
与
-s
类似,但会作为登录外壳启动外壳。这表示系统会处理该外壳的启动文件(.profile
等),并会将当前的工作目录设置为目标用户的主目录。tux:~ >
sudo -i root's password:root:~ #
exittux:~ >
默认情况下,sudo
不会传播环境变量。可以使用 env_reset
选项更改此行为(请参见有用的标志和选项)。
2.2 配置 sudo
#
sudo
提供各种可配置的选项。
如果您不小心将自己锁定在 sudo
之外,可以使用 su
-
和 root
口令来启动 root 外壳。要修复该错误,请运行 visudo
。
下面所述的示例规则纯粹用于演示目的。请使用这些示例来了解 sudo
配置文件的一般语法。不要在现实设置中使用它们,因为它们不能反映这些环境的复杂性。
2.2.1 sudo
配置最佳实践 #
在开始之前,请注意以下有关维护 sudo
配置的几条基本规则:
- 始终使用
visudo
来编辑sudo
配置文件 应使用
visudo
命令对sudo
配置进行任何更改。visudo
是一个定制的工具,可用于编辑sudo
配置文件和运行基本语法检查,以确保配置保持完整且能正常运行。错误的sudo
配置可能导致用户被锁定在自己的系统之外。- 始终在
/etc/sudoers.d/
下创建自定义配置 自定义配置必须位于
/etc/sudoers.d/
下才能由sudo
拉入。自定义配置文件中的设置优先于/etc/sudoers
包含的默认配置中的设置。- 始终注意配置读取顺序
为确保以正确的顺序读取自定义配置,请在配置前面加上数字作为前缀。使用前导零来建立文件的读取顺序。例如,
01_myfirstconfig
在10_myotherconfig
之前分析。如果在某个文件中设置了一个指令,而该文件是在包含冲突信息的另一个文件之前读取的,则会应用最后读取的指令。- 始终使用描述性文件名
使用能够提示配置文件作用的文件名。这可以帮助您跟踪
sudo
设置的预期功能。
2.2.2 创建用户特定的配置文件 #
创建一个 sudo
配置文件,以允许普通用户 (tux
) 使用自己的口令(而不是 root
口令)运行 useradd
命令。
以系统管理员 (
root
) 身份启动visudo
,创建一个用于保存新用户特定的指令的自定义配置文件。使用带编号的描述性名称:#
visudo -f /etc/sudoers.d/02_usermanagement
创建一条规则,以允许
tux
在此sudo
配置应用到的整个环境中执行/usr/sbin/useradd
二进制文件:tux1 ALL2 = /usr/sbin/useradd3
指定用户或组。按名称或
#UID
列出用户,按%GROUPNAME
列出组。用逗号分隔多项。要否定项,请使用!
。指定一个或多个主机(用逗号分隔)。使用完全限定的主机名或 IP 地址。添加
ALL
以在所有主机上全局强制实施此设置。使用!
进行否定。指定一个或多个可执行文件(用逗号分隔)。指定可执行文件时,请务必注意以下规则:
/usr/sbin/useradd
在不添加任何其他选项的情况下,此操作允许执行每个可能的
useradd
命令。/usr/sbin/useradd -c
如果您显式指定某个选项,则该选项是唯一允许的选项。在上面指定的用户无法使用其他任何选项。
/usr/sbin/useradd ""
这样,用户只能单纯调用
useradd
,而根本不能使用任何选项。
在上面的示例中,您可能希望允许使用所有选项和子命令,或者出于安全考虑将允许的选项和子命令限制为少数几个,但在这种情况下,完全禁止用户指定任何选项是毫无意义的。
要让用户使用自己的口令而不是
root
口令,请添加以下一行内容:Defaults:tux !targetpw
如果启用,此标志要求用户输入目标用户(即
root
)的口令。此标志在任何 SUSE Linux Enterprise Server 系统上默认都处于启用状态。使用!
可以对其否定,要求用户只输入自己的口令而不是root
口令。保存配置,退出编辑器,并打开另一个外壳来测试
sudo
是否遵循您的新配置。
2.2.3 通过对项目进行分组来创建自定义配置 #
修改例 2.1 “创建用户特定的配置文件”中的配置,使一组命名用户无需输入 root
口令即可运行 useradd
命令。另外,将 usermod
和 userdel
添加到此组可用的命令列表中。
要修改示例配置,请以系统管理员身份使用
visudo
将其打开:#
visudo /etc/sudoers.d/02_usermanagement
使用逗号分隔的列表将更多用户添加到规则:
tux, wilber ALL = /usr/sbin/useradd
要允许列出的用户执行一系列命令,请将这些命令指定为逗号分隔的列表:
tux, wilber ALL = /usr/sbin/useradd, /usr/sbin/usermod, /usr/sbin/userdel
要让列出的用户使用自己的口令而不是
root
口令,请添加以下一行内容:Defaults:tux, wilber !targetpw
如果启用,此标志要求列出的用户输入目标用户(即
root
)的口令。此标志在任何 SUSE Linux Enterprise Server 系统上默认都处于启用状态。使用!
可以对其否定,要求列出的用户只输入自己的口令而不是root
口令。保存配置,退出编辑器,并打开另一个外壳来测试
sudo
是否遵循您的新配置。
2.2.4 通过应用别名简化配置 #
使用别名可以进一步简化例 2.2 “通过对项目进行分组来创建自定义配置”中的自定义配置。对项目进行分组在一定程度上有所帮助,但使用用户、命令和主机的全局别名是使 sudo
配置保持整洁精简的最有效方法。
使用别名和组(而不是列表)是处理设置更改的更好方法。如果某个用户离职,只需将其从别名声明文件内的全局 User_Alias
声明中去除即可,而无需寻源到所有单独的自定义配置文件。该过程同样适用于任何其他类型的别名(Host_Alias
、Cmnd_Alias
和 Runas_Alias
)。
创建一个新文件来保存全局别名定义:
#
visudo /etc/sudoers.d/01_aliases
添加以下一行内容以创建
TEAMLEADERS
别名:User_Alias TEAMLEADERS = tux, wilber
添加以下一行内容以创建
USERMANAGEMENT
别名:Cmnd_Alias USERMANAGEMENT = /usr/sbin/useradd, /usr/sbin/usermod, /usr/sbin/userdel
保存更改并退出
visudo
。以系统管理员身份启动
visudo
以编辑示例配置文件:#
visudo -f /etc/sudoers.d/02_usermanagement
删除先前的规则并将其替换为以下规则,该规则使用您刚刚定义的别名:
TEAMLEADERS ALL = USERMANAGEMENT
要让
User_Alias
定义的所有用户都使用自己的口令而不是root
口令,请添加以下一行内容:Defaults:TEAMLEADERS !targetpw
保存配置,退出编辑器,并打开另一个外壳来测试
sudo
是否遵循您的新配置。
2.2.5 sudoers 基本配置语法 #
sudoers 配置文件包含两种类型的选项:字符串和标志。字符串可以包含任何值,而标志则只能在“ON”或“OFF”之间切换。sudoers 配置文件最重要的语法构造如下:
# Everything on a line after # is ignored 1 Defaults !insults # Disable the insults flag 2 Defaults env_keep += "DISPLAY HOME" # Add DISPLAY and HOME to env_keep tux ALL = NOPASSWD: /usr/bin/frobnicate, PASSWD: /usr/bin/journalctl 3
存在两个例外: | |
去除 | |
targetpw
此标志控制调用用户是需要输入目标用户(例如
root
)的口令 (ON) 还是需要输入调用用户的口令 (OFF)。Defaults targetpw # Turn targetpw flag ON
rootpw
如果设置,
sudo
将提示输入root
口令。默认值为 OFF。Defaults !rootpw # Turn rootpw flag OFF
env_reset
如果设置,
sudo
会构造一个具有TERM
、PATH
、HOME
、MAIL
、SHELL
、LOGNAME
、USER
、USERNAME
和SUDO_*
的极简环境。此外,会从调用环境导入env_keep
中列出的变量。默认值为“ON”。Defaults env_reset # Turn env_reset flag ON
env_keep
env_reset
标志设为“ON”时要保留的环境变量列表。# Set env_keep to contain EDITOR and PROMPT Defaults env_keep = "EDITOR PROMPT" Defaults env_keep += "JRE_HOME" # Add JRE_HOME Defaults env_keep -= "JRE_HOME" # Remove JRE_HOME
env_delete
env_reset
标志设为“OFF”时要去除的环境变量列表。# Set env_delete to contain EDITOR and PROMPT Defaults env_delete = "EDITOR PROMPT" Defaults env_delete += "JRE_HOME" # Add JRE_HOME Defaults env_delete -= "JRE_HOME" # Remove JRE_HOME
还可以使用 Defaults
令牌为用户、主机和命令集合创建别名。并且,可以仅将选项应用到特定用户集。
有关 sudoers 配置文件的详细信息,请参见 man 5
sudoers
。
2.2.6 基本 sudoers 规则 #
每条规则都遵循以下模式([]
标记的是可选部分):
#Who Where As whom Tag What User_List Host_List = [(User_List)] [NOPASSWD:|PASSWD:] Cmnd_List
User_List
一个或多个(用逗号分隔)标识符:用户名、
%GROUPNAME
格式的组或#UID
格式的用户 ID。可以使用!
前缀指定求反。Host_List
一个或多个(用逗号分隔)标识符:(完全限定的)主机名或 IP 地址。可以使用
!
前缀指定求反。Host_List
的常用选项为ALL
。NOPASSWD:|PASSWD:
如果用户在
NOPASSWD:
后面运行的命令与Cmd_List
匹配,系统不会提示用户输入口令。PASSWD
为默认选项。仅当PASSWD
和NOPASSWD
位于同一行时,才需要指定此选项:tux ALL = PASSWD: /usr/bin/foo, NOPASSWD: /usr/bin/bar
Cmnd_List
一个或多个(用逗号分隔)说明符:可执行文件的路径,后跟允许使用的可选参数。
/usr/bin/foo # Anything allowed /usr/bin/foo bar # Only "/usr/bin/foo bar" allowed /usr/bin/foo "" # No arguments allowed
ALL
可以用作 User_List
、Host_List
和 Cmnd_List
。
允许 tux
在无需输入口令的情况下以 root 身份运行所有命令的规则:
tux ALL = NOPASSWD: ALL
允许 tux
运行 systemctl restart
apache2
的规则:
tux ALL = /usr/bin/systemctl restart apache2
允许 tux
在不带参数的情况下以 admin
身份运行 wall
的规则:
tux ALL = (admin) /usr/bin/wall ""
使用 ALL ALL =
ALL
之类的规则时切勿不带 Defaults targetpw
。否则,任何人都能够以 root
身份运行命令。
在 sudoers
文件中指定组名时,请确保使用 NetBIOS 域名而不是领域,例如:
%DOMAIN\\GROUP_NAME ALL = (ALL) ALL
请注意,使用 winbindd 时,其格式还取决于 smb.conf
文件中的 winbind separator
选项。默认为 \
.例如,如果将其更改为 +
,则 sudoers
文件中的帐户格式必须为 DOMAIN+GROUP_NAME
。
2.3 对 X.Org 应用程序使用 sudo
#
使用 sudo
启动图形应用程序通常会导致以下错误:
>
sudo
xterm xterm: Xt error: Can't open display: %s xterm: DISPLAY is not set
一种简单的解决方法是使用 xhost 来暂时允许 root 用户访问本地用户的 X 会话。可使用以下命令完成此操作:
xhost si:localuser:root
以下命令可去除授予的访问权限:
xhost -si:localuser:root
以 root 特权运行图形应用程序存在安全隐患。建议仅在例外的情况下,才启用对图形应用程序的 root 访问权限。另外,建议在关闭图形应用程序后,立即撤消授予的 root 访问权限。
2.4 更多信息 #
sudo --help
命令提供可用命令行选项的简要概述,而 man sudoers
命令则会提供有关 sudoers
及其配置的详细信息。