documentation.suse.com / 使用 sudo 配置超级用户特权
SUSE Linux Micro 6.2

使用 sudo 配置超级用户特权

出版日期:2025 年 11 月 04 日
内容

熟悉有关 sudo 配置的基础知识,并了解如何使用 sudo 委托超级用户特权。本文提供了深入的 sudo 配置信息,并未就如何构建全面安全的 sudo 策略提供任何建议。与安全相关的策略非常复杂,在很大程度上取决于它们是针对什么环境创建的。

原因

某些命令需要管理员或 root 特权。使用 sudo,可以将执行这些命令的特权委托给特定的用户或组。

工作量

读完本文最多需要 20 分钟。编写第一个 sudo 配置规则只需几分钟时间,但建立一个可在环境中正常运行的 sudo 配置需要相当长的时间,具体取决于设置复杂性。

目标

了解 sudo 配置的基本方面。掌握 sudo 配置的常见使用场景。了解如何在 sudo 设置中使用用户、用户组和别名。熟悉 sudo 最佳实践和查错技巧。

要求

1 sudo 配置简介

sudo 提供了一种安全有效的方式将超级用户特权委托给特定用户或组。

Linux 系统上的某些操作需要 root 或管理员特权。自行管理系统的家庭用户无需分配超级用户权限,因为在此场景下,管理员与普通用户为同一人。但一旦系统纳入到包含多个用户、用户组及主机的大型环境,就必须明确控制谁被允许在何处执行何种操作。与此同时,为所有用户和用户组提供完成其任务所需的必要权限也十分重要。

重要
重要

sudo-policy-wheel-auth-self 软件包所实施的新策略中,wheel 用户组用于确定用户是否可通过输入自身口令获取 root 权限。由 Agama 安装程序创建的第一个用户会自动加入 wheel 用户组。

此外,运行 sudo 命令时的规则如下:

  • 如果您属于 wheel 用户组,系统会提示您输入自身的用户口令。

  • 如果您不属于 wheel 用户组,系统会提示您输入 root 口令。

sudo 可提供以下优势:

增强的系统安全性

sudo 提供对用户、组、主机和命令的精细控制,从而可以通过降低入侵者或系统用户恶意或意外造成损坏的风险,来提高系统安全性。

完整的审计追踪

每当用户切换特权时,这种行为就会出现在系统日志中,并且该用户以提升的特权执行的所有操作都可以追溯到该用户。

委托 root 专属任务的方式

使用 sudo,系统管理员可以允许单个用户或组执行特定的任务,而无需输入 root 口令并切换到 root 帐户。

2 创建自定义 sudo 配置

您需要了解如何构建简单的示例自定义 sudo 配置并逐步扩展它。创建组并使用别名可使自定义配置保持精简且高效。

重要
重要

SUSE Linux Enterprise Server 15 迁移时,系统中会存在 /etc/sudoers 文件。如果 /etc/sudoers 文件存在,/usr/etc/sudoers 文件将被忽略。只要用户未对 /etc/sudoers 文件进行重大修改,系统仍会读取 /etc/sudoers.d/ 目录下的配置。

SUSE Linux Enterprise Server 15 迁移时,建议未修改过 /etc/sudoers 文件的用户将其去除。如果用户已修改过 /etc/sudoers 文件,需先将修改后的文件移至 /etc/sudoers.d 目录,再去除原文件。

警告
警告:示例配置仅用于演示目的

下面所述的示例规则仅用于演示目的。请使用这些示例来了解 sudo 配置文件的一般语法。不要在现实设置中使用它们,因为它们不能反映这些环境的复杂性。

2.1 sudo 配置最佳实践

在开始之前,请注意以下有关维护 sudo 配置的几条基本规则:

始终使用 visudo -f 命令编辑 /etc/sudoers.d/ 目录

sudo 配置的任何更改都应使用 visudo 命令来进行。visudo 是一个定制的工具,可用于编辑 sudo 配置文件和运行基本语法检查,以确保配置保持完整且能正常运行。错误的 sudo 配置可能导致用户被锁定在自己的系统之外。

始终在 /etc/sudoers.d/ 下创建自定义配置

自定义配置必须位于 /etc/sudoers.d/ 目录下,sudo 才会拉取该配置。自定义配置文件中的设置优先于 /usr/etc/sudoers 包含的默认配置中的设置。

始终注意配置读取顺序

为确保以正确的顺序读取自定义配置,请在配置前面加上数字作为前缀。使用前导零来建立文件的读取顺序。例如,01_myfirstconfig10_myotherconfig 之前分析。如果在某个文件中设置了一个指令,而该文件是在包含冲突信息的另一个文件之前读取的,则会应用最后读取的指令。

始终使用描述性文件名

使用能够提示配置文件作用的文件名。这可以帮助您跟踪 sudo 设置的预期功能。

2.2 创建用户特定的配置文件

创建一个 sudo 配置文件,以允许普通用户 (tux) 使用自己的口令(而不是 root 口令)运行 useradd 命令。

例 1︰ 创建用户特定的配置文件
  1. 以系统管理员 (root) 身份启动 visudo,创建一个用于保存新用户特定的指令的自定义配置文件。使用带编号的描述性名称:

    # visudo -f /etc/sudoers.d/02_usermanagement
  2. 创建一条规则,以允许 tux 在此 sudo 配置应用到的整个环境中执行 /usr/sbin/useradd 二进制文件:

    tux1 ALL2 = /usr/sbin/useradd3

    1

    指定用户或组。按名称或 #UID 列出用户,按 %GROUPNAME 列出组。如果此处有多个项目,请用逗号分隔。要否定项,请使用 !

    2

    指定一个或多个主机(用逗号分隔)。使用完全限定的主机名或 IP 地址。添加 ALL 以在所有主机上全局强制实施此设置。使用 ! 进行否定。

    3

    指定一个或多个可执行文件(用逗号分隔)。指定可执行文件时,请务必注意以下规则:

    /usr/sbin/useradd

    在不添加任何其他选项的情况下,此操作允许执行每个可能的 useradd 命令。

    /usr/sbin/useradd -c

    如果您明确指定某个选项,则该选项是唯一允许的选项。在上面指定的用户无法使用其他任何选项。

    /usr/sbin/useradd ""

    这样,用户只能单纯调用 useradd,而根本不能使用任何选项。

    在上面的示例中,您可能希望允许使用所有选项和子命令,或者出于安全原因将允许的选项和子命令限制为少数几个,但在这种情况下,完全禁止用户指定任何选项是毫无意义的。

  3. 保存配置,退出编辑器,并打开另一个外壳来测试 sudo 是否遵循您的新配置。

2.3 通过对项目进行分组来创建自定义配置

修改例 1 “创建用户特定的配置文件”中的配置,使一组命名用户无需输入 root 口令即可运行 useradd 命令。另外,将 usermoduserdel 添加到此组可用的命令列表中。

例 2︰ 通过对项目进行分组来创建自定义配置
  1. 要修改示例配置,请以系统管理员身份使用 visudo 将其打开:

    # visudo /etc/sudoers.d/02_usermanagement
  2. 使用逗号分隔的列表将更多用户添加到规则:

    tux, wilber ALL = /usr/sbin/useradd
  3. 要允许列出的用户执行一系列命令,请将这些命令指定为逗号分隔的列表:

    tux, wilber ALL = /usr/sbin/useradd, /usr/sbin/usermod, /usr/sbin/userdel
  4. 保存配置,退出编辑器,并打开另一个外壳来测试 sudo 是否遵循您的新配置。

2.4 通过应用别名简化配置

使用别名可以进一步简化例 2 “通过对项目进行分组来创建自定义配置”中的自定义配置。对项目进行分组在一定程度上有所帮助,但使用用户、命令和主机的全局别名是使 sudo 配置保持整洁精简的最有效方法。

使用别名和组(而不是列表)是应对环境设置变更的更优方式。例如,当某用户离职时,无需逐一检查所有独立的自定义配置文件,只需在别名声明文件的全局 User_Alias 声明中去除该用户即可。该过程同样适用于任何其他类型的别名(Host_AliasCmnd_AliasRunas_Alias)。

例 3︰ 通过应用别名简化配置
  1. 创建一个新文件来保存全局别名定义:

    # visudo /etc/sudoers.d/01_aliases
  2. 添加以下一行内容以创建 TEAMLEADERS 别名:

    User_Alias    TEAMLEADERS = tux, wilber
  3. 添加以下一行内容以创建 USERMANAGEMENT 别名:

    Cmnd_Alias    USERMANAGEMENT = /usr/sbin/useradd, /usr/sbin/usermod, /usr/sbin/userdel
  4. 保存更改并退出 visudo

  5. 以系统管理员身份启动 visudo 以编辑示例配置文件:

    # visudo -f /etc/sudoers.d/02_usermanagement
  6. 删除先前的规则并将其替换为以下规则,该规则使用您刚刚定义的别名:

    TEAMLEADERS ALL = USERMANAGEMENT
  7. 保存配置,退出编辑器,并打开另一个外壳来测试 sudo 是否遵循您的新配置。

注意
注意:更多信息

第 7 节 “sudo 配置参考”中查找 sudo 配置语法的更详细说明,并参见 sudo 的手册页。

3 更改 sudo 口令提示超时

了解如何更改超时设置,以便在执行需要 root 特权的命令时,不会每执行一个命令都出现输入 root 口令的提示。

首次运行以 sudo 开头的命令时,系统会提示您输入 root 口令。该口令将会在一段时间内保持有效。一旦口令失效,系统会再次提示用户输入口令。要延长或缩短在执行需要 root 特权的命令时实施的超时,请对 sudo 配置文件进行以下更改。请务必注意,虽然系统提示用户输入 root 口令,但他们并不属于 wheel 用户组。

警告
警告: 不要向 root 特权授予不受限的无口令访问权限

出于安全原因,请不要向 root 特权授予不受限的访问权限。相反,请设置合理的超时,以防任何入侵者滥用 root 帐户。

过程 1︰ 更改 sudo 口令提示的超时
  1. 以系统管理员身份,使用以下命令为时戳配置创建一个新的 sudo 配置文件:

    # visudo --f=/etc/sudoers.d/timestamp_timeout

    使用 root 口令成功完成身份验证后,将打开该文件。

  2. 启用编辑功能并添加 timestamp_timeout= 一行。输入时戳值。

    例如,要将超时缩短为三分钟,请输入:

    Defaults timestamp_timeout=3

    如果时戳设置为零,则每次执行 sudo 命令时,系统都会提示您输入 root 口令。

  3. 保存更改并关闭该文件。

您已创建 sudo 配置文件,并缩短了执行 sudo 命令的超时设置。

4 使用 root 特权启动外壳

使用 sudo -ssudo -i 命令以永久性 root 特权启动外壳。使用这两个命令时,系统只会提示您输入 root 口令一次。请务必注意,如果用户属于 wheel 用户组,系统会提示他们输入自己的口令。否则,系统会提示其输入 root 口令。

4.1 sudo -ssudo -i 的区别

如果每次以 root 身份运行命令都必须输入 sudo,您可能会觉得非常不便。您可以使用一个内置机制来以永久性 root 特权启动外壳。为此可以使用两个命令选项:

  • sudo -s 使用当前用户的环境启动外壳,并提供几个特权控制措施。要运行此命令,请输入 root 口令。

  • sudo -i 使用干净的环境将外壳作为交互式登录外壳启动。要运行此命令,请输入 root 口令。

使用这两个命令时,外壳将通过新环境启动,您将以 root 身份登录。在该外壳中执行的任何后续命令都将以提升的特权运行,您无需再次输入口令。当您关闭外壳时,此环境将会终止,在执行另一个 sudo 命令时,您必须再次输入口令。

4.2 使用 sudo -s 启动外壳

sudo -s 命令启动交互式非登录外壳。使用 root 口令成功完成身份验证后,所有后续命令都将以提升的特权执行。

SHELL 环境变量或用户的默认外壳指定了要打开哪个外壳。如果此变量为空,则会选取 /etc/passwd 中定义的外壳。

默认情况下,sudo -s 命令从前一用户的目录运行,因为目标用户会继承前一用户的环境。该命令还会记录到您的历史中。

要以永久提升的特权启动外壳,请输入以下命令:

tux:~ > sudo -s
[sudo] password for root:
root:/home/tux # exittux:~ > 

提示符从 > 更改为 #

您已使用永久提升的特权启动了外壳。执行所有后续命令时,系统不会再次提示输入口令。

4.3 使用 sudo -i 启动外壳

sudo -isudo -s 命令行选项类似,但它会启动交互式登录外壳。使用 sudo -s 命令时,目标用户将继承前一用户的环境。您可以使用 sudo -i 命令来防止出现这种情况,运行此命令后,目标用户将获得一个干净的环境,并可以在他们自己的 $HOME 目录开始工作。

要使用 sudo -i 运行命令,请输入以下命令:

tux:~ > sudo -i
[sudo] password for root:
root:~ # exittux:~ > 

您已使用永久提升的特权启动了外壳,并且命令已记录到您的历史记录中。执行所有后续命令时,系统不会再次提示输入口令。

5 sudo 最佳实践

了解 sudo 的一些最佳实践,以控制系统访问权限并提高用户的工作效率。

sudo 配置进行全面测试和审计

要构建真正高效且安全的 sudo 配置框架,请制定例行性的定期测试和审计流程。找出可能的漏洞并予以处理。不要出于便利而疏忽安全。

限制 sudo 超时

出于安全原因,请不要向 root 特权授予不受限的访问权限。相反,请设置合理的超时,以防任何入侵者滥用 root 帐户。有关详细信息,请参见第 3 节 “更改 sudo 口令提示超时”

使用 visudo 命令

使用 visudo -f 命令可以安全地编辑 /usr/etc/sudoers 文件,因为它会在保存更改之前检查文件的语法。这是一种预防措施,旨在纠正任何可能破坏系统的错误。除了基本的语法检查之外,您还可以运行 visudo -c 来检查整个 sudo 配置框架是否以正确的顺序进行解析,且不包含错误。

按组而不是按个人管理用户

尽可能使 sudo 配置保持精简且易于管理。应采用以下方式来管理用户:将用户添加到组,然后向这些组而不是个人授予特权。这样可以方便地通过更改组设置来添加或去除用户,而不必在整个配置中查找用户。

允许示例 %admingrp 组中的所有用户执行所有命令的示例规则:

%admingrp ALL = (ALL) ALL
限制二进制文件的路径

使用 secure_path 指令限制用户可以在哪些区域执行命令。以下示例是 SUSE Linux Enterprise Server 随附的默认设置。

Defaults secure_path="/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/bin:/usr/local/sbin"
保持 sudo 日志记录透明

sudo 记录到标准日志文件,但其中的日志项很容易被忽略。将以下规则添加到您的配置,以指定专用的 sudo 日志文件。

Defaults logfile=/var/log/sudo.log

6 查错

了解如何对 sudo 配置问题进行调试和查错。

6.1 /etc/sudoers.d/ 下的自定义配置被忽略

/etc/sudoers 中的 #includedir 指令会忽略以 ~ 字符结尾或包含 . 字符的文件。这是为了避免软件包管理器提供的配置文件(包含 .)或编辑器的临时文件或备份文件(以 ~ 结尾)出现问题。请确保自定义配置文件的名称既不包含这些字符,也不以这些字符结尾。如果存在这种情况,请重命名这些文件。

6.2 自定义指令冲突

配置文件的读取顺序决定了何时应用 sudo 配置指令。/etc/sudoers.d/ 下的文件中的指令优先于 /etc/sudoers 中的相同指令。如果 /etc/sudoers.d/ 中指定的自定义指令不起作用,请使用 visudo -c 检查文件的读取顺序。根据需要调整顺序。

6.3 由于 sudo 配置损坏而被锁定

如果您不小心破坏了系统的 sudo 配置,因而将自己锁定在 sudo 之外,可以使用 su -root 口令来启动 root 外壳。运行 visudo -c 以检查错误,然后使用 visudo 修复错误。

7 sudo 配置参考

本章提供基本的 sudo 配置参考,以帮助您了解和维护默认和自定义的 sudo 配置。

7.1 sudoers 配置语法

sudoers 配置文件包含两种类型的选项:字符串和标志。字符串可以包含任何值,而标志则只能在“ON”或“OFF”之间切换。sudoers 配置文件的最重要语法构造如下:

# Everything on a line after # is ignored1
Defaults !insults # Disable the insults flag2
Defaults env_keep += "DISPLAY HOME" # Add DISPLAY and HOME to env_keep3
tux ALL = NOPASSWD: /usr/bin/frobnicate, PASSWD: /usr/bin/journalctl4

1

存在两个例外:#include#includedir 是普通命令。较新版本不再使用 #。取而代之的是,include 指令现在前面带有 @。为了向后兼容,仍支持 # 表示法。

2

去除 ! 字符会将所需标志设置为 ON。

3

指定在启用 env_reset 时应保留的环境变量列表。

4

一个复杂的规则,规定用户 tux 必须输入口令才能运行 /usr/bin/journalctl,但不需要输入口令即可在所有主机上运行 /usr/bin/frobnicate

有用的标志和选项
env_reset

如果设置,sudo 会构造一个具有 TERMPATHHOMEMAILSHELLLOGNAMEUSERUSERNAMESUDO_* 的极简环境。此外,会从调用环境导入 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

7.2 基本 sudoers 规则

每条规则都遵循以下模式([] 标记的是可选部分):

#Who      Where         As whom      Tag                What
User_List Host_List = [(User_List)] [NOPASSWD:|PASSWD:] Cmnd_List
sudoers 规则语法
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_ListHost_ListCmnd_List

7.3 使用别名简化 sudoers

管理员可以通过在组项目中引入别名,来避免维护一组重复的规则或逐个地维护规则。别名的语法与规则的语法相同。支持以下类型的别名:

User_Alias

用户名列表

Runas_Alias

按 UID 划分的用户组

Host_Alias

主机名列表

Cmnd_Alias

命令、目录和别名的列表

将别名视为用户、组、命令和主机的命名列表。以下示例展示了别名的强大作用:

Host_Alias    WEBSERVERS = www1, www2, www31
User_Alias    ADMINS = tux, wilber, suzanne2
Cmnd_Alias    REBOOT = /sbin/halt, /sbin/reboot, /sbin/poweroff3
ADMINS WEBSERVERS = REBOOT4

1

这三个服务器已分组到一个 Host_Alias WEBSERVERS。您可以使用完全限定的主机名或 IP 地址。

2

与上面分组的主机类似,此处列出了组用户甚至用户组(例如 %wheel)。像往常一样,否定是通过 ! 前缀实现的。

3

指定在同一上下文中使用的一组命令。

4

所有别名包含在一条规则中,该规则规定,User_Alias 指定的所有用户都可以在 Host_Alias 中命名的所有主机上执行 Cmnd_Alias 下指定的一组命令。

概括而言,别名可帮助管理员保持 sudoers 精简且易管理(因此保持其安全性)。例如,如果某个用户离职,您只需从 User_Alias 语句以及此人所属的任何系统组中删除此人的姓名一次,而不必搜索包含此特定用户的所有规则。