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 -un1 tux>sudoid -unroot's password:2 root>id -untux3>sudoid -un4 root
| 
 | |
| 在输入过程中不会显示口令,无论是明文还是屏蔽字符都不显示。 | |
| 
            只有以  | |
| 
            提升的特权会持续一段时间,因此您不必再次提供  | 
          使用 sudo 时,I/O 重定向不起作用:
        
>sudoecho s > /proc/sysrq-trigger bash: /proc/sysrq-trigger: Permission denied>sudocat < /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 #exit- tux:~ >
- sudo -i (<command>)
- 与 - -s类似,但会作为登录外壳启动外壳。这表示系统会处理该外壳的启动文件(- .profile等),并会将当前的工作目录设置为目标用户的主目录。- tux:~ >sudo -i root's password:- root:~ #exit- tux:~ >
2.2 配置 sudo #
sudo 提供各种可配置的选项。
    
        如果您不小心将自己锁定在 sudo 之外,可以使用 su
        - 和 root 口令来启动 root 外壳。要修复该错误,请运行 visudo。
      
        下面所述的示例规则纯粹用于演示目的。请使用这些示例来了解 sudo 配置文件的一般语法。不要在现实设置中使用它们,因为它们不能反映这些环境的复杂性。
      
2.2.1 sudo 配置最佳实践 #
        在开始之前,请注意以下有关维护 sudo 配置的几条基本规则:
      
- 始终使用 visudo来编辑sudo配置文件
- 对 - sudo配置的任何更改都应使用- visudo命令来进行。- 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 启动图形应用程序通常会导致以下错误:
    
>sudoxterm 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 及其配置的详细信息。