跳到内容跳到页面导航:上一页 [access key p]/下一页 [access key n]
documentation.suse.com / 使用 sudo 配置超级用户特权

使用 sudo 配置超级用户特权

出版日期:2025-03-06
解释

熟悉有关 sudo 配置的基础知识,并了解如何使用 sudo 委托超级用户特权。

原因

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

工作量

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

目标

了解 sudo 配置的基本方面。应对 sudo 配置的常见用例。了解如何在 sudo 设置中使用用户、用户组和别名。熟悉 sudo 最佳实践和查错。

要求

1 sudo 配置简介

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

Linux 系统上的某些操作需要 root 或管理员特权。管理自己系统的家庭用户不必委托超级用户特权,因为在这种情况下,管理员和普通用户是同一个人。但是,一旦系统成为包含多个用户、组和主机的更大系统环境的一员,控制谁有权在哪个位置执行哪种操作就变得至关重要。同时,为所有用户和组提供必要的特权来执行其任务也很重要。

sudo 旨在帮助解决这些需求。它提供:

增强的系统安全性

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

完整的审计追踪

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

委托 root 特定任务的方式

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

重要
重要:如何阅读本文

本文提供深入的 sudo 配置信息。但是,它不提供任何有关如何构建全面且安全的 sudo 策略的建议。与安全相关的策略非常复杂,在很大程度上取决于它们是针对什么环境创建的。

2 创建自定义 sudo 配置

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

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

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

2.1 sudo 配置最佳实践

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

始终使用 visudo 来编辑 sudo 配置文件

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

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

自定义配置必须位于 /etc/sudoers.d/ 下才能由 sudo 拉入。自定义配置文件中的设置优先于 /etc/sudoers 包含的默认配置中的设置。

始终注意配置读取顺序

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

始终使用描述性文件名

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

提示
提示:sudo 配置和不可变文件系统

不可变文件系统是一旦安装即无法更改的文件系统,它是只读的。如果您使用的 SUSE 产品依赖于不可变文件系统,则该产品附带的 sudo 默认配置将安装在 /usr/etc/sudoers 下,并且任何预先配置的调整都位于 /usr/etc/sudoers.d/ 下。

您自己的自定义配置位于 /etc/sudoers.d/ 下,并优先于 /usr/etc/sudoers.d/ 中提供的任何内容。如果不存在现有的 sudoers 文件,visudo 命令可打开 /usr/etc/sudoers 并将更改的文件保存到 /etc/sudoers。如果已有该文件,visudo 将打开该文件并将数据写入其中。位于 /etc/ 下的实例优先于位于 /usr/etc/ 下的实例。这样,用户所做的配置调整就不会因更新而被破坏。

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. 要让用户使用自己的口令而不是 root 口令,请添加以下一行内容:

    Defaults:tux !targetpw

    激活后,此标志要求用户输入目标用户(即 root)的口令。此标志在任何 SLE Micro 系统上默认都处于启用状态。使用 ! 可以对其否定,要求用户只输入自己的口令而不是 root 口令。

  4. 保存配置,退出编辑器,并打开另一个外壳来测试 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. 要让列出的用户使用自己的口令而不是 root 口令,请添加以下一行内容:

    Defaults:tux, wilber !targetpw

    如果处于启用状态,此标志要求列出的用户输入目标用户(即 root)的口令。此标志在任何 SLE Micro 系统上默认都处于启用状态。使用 ! 可以对其否定,要求列出的用户只输入自己的口令而不是 root 口令。

  5. 保存配置,退出编辑器,并打开另一个外壳来测试 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. 要让 User_Alias 定义的所有用户都使用自己的口令而不是 root 口令,请添加以下一行内容:

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

注意
注意:更多信息

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

3 更改 sudo 口令提示超时

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

首次运行以 sudo 开头的命令时,系统会提示您输入 root 口令。该口令将保持有效一段时间。一旦口令失效,系统会再次提示用户输入口令。要延长或缩短在执行需要 root 特权的命令时实施的超时,请对 sudo 配置文件进行以下更改。

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

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

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

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

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

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

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

    timestamp_timeout=3

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

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

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

4 使用 root 特权启动外壳

使用 sudo -ssudo -i 命令以永久性 root 特权启动外壳。使用这两个命令时,系统只会提示您输入 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 # exit
tux:~ > 

提示符从 > 更改为 #

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

4.3 使用 sudo -i 启动外壳

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

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

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

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

5 sudo 最佳实践

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

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

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

将自定义的 sudo 配置保存在单独的文件中

sudo 的主要策略配置文件为 /etc/sudoers。此文件通过系统软件包提供,对其进行更改可能会破坏更新。因此,请在 /etc/sudoers.d/ 目录下创建单独的配置文件用于保存自定义设置。默认情况下,这些设置将由 /etc/sudoers 中的某个指令拉入。

限制 sudo 超时

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

使用 visudo 命令

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

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

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

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

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

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

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

有用的标志和选项
targetpw

如果设置此项,则 sudo 会提示您输入在 -u 选项中指定的用户口令;如果未使用 -u,则提示您输入 root 口令。默认值为“ON”。

Defaults targetpw # Turn targetpw flag ON
rootpw

如果设置,sudo 将提示输入 root 口令。默认值为 OFF。

Defaults !rootpw # Turn rootpw flag OFF
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 语句以及此人所属的任何系统组中删除此人的姓名一次,而不必搜索包含此特定用户的所有规则。