Sudo (简体中文)

From ArchWiki
翻译状态:本文是 Sudo翻译。上次翻译日期:2019-03-15。如果英文版本有所更改,则您可以帮助同步翻译。

Sudo(substitute user do) 使得系统管理员可以授权特定用户或用户组作为 root 或他用户执行某些(或所有)命令,同时还能够对命令及其参数提供审核跟踪。

用户可以选择用 su 切换到 root 用户运行命令,但是这种方式会启动一个 root shell 并允许用户运行之后的所有的命令。而 sudo 可以针对单个命令、仅在需要时授予临时权限,减少因为执行错误命令损坏系统的可能性。sudo 也能以其他用户身份执行命令并且记录用户执行的命令,以及失败的权限申请。

安装

安装软件包 sudo

使用

在配置之前,普通用户还无法使用sudo。所以请认真阅读配置部分。

普通用户只需在命令前加上sudo,即可使用 root 特权执行命令:

$ sudo cmd

参见:sudo(8)

配置

有关配置和密码过期等问题的更多信息,请阅读 man sudoers

查看当前设置

命令 sudo -ll 可以显示当前的 sudo 配置; 命令 sudo -lU user 可以查看某个特定用户的设置。

使用 visudo

sudo的配置文件是/etc/sudoersvisudo会锁住sudoers文件,保存修改到临时文件,然后检查文件格式,确保正确后才会覆盖sudoers文件。必须保证sudoers格式正确,否则sudo将无法运行。

警告: /etc/sudoers格式错误会导致sudo不可用。必须使用visudo编辑该文件防止出错。

visudo调用的默认编辑器是vi。官方仓库里的 sudo 编译时开启了--with-env-editor,会采用环境变量 VISUALEDITOR的设置。如果设置了VISUAL 就不会使用EDITOR

如果要临时使用其他编辑器,在该命令前加上EDITOR环境变量即可。例如,要使用 nano,用root运行以下命令:

# EDITOR=nano visudo

要永久设置编辑器,请查看 定义本地环境变量.

系统级的设置可以把编辑器设置到 /etc/sudoers。以 nano 为例,使用visudo打开该文件,加入以下内容:

# Defaults specification
# Reset environment by default
Defaults      env_reset
# Set default EDITOR to vim, and do not allow visudo to use EDITOR/VISUAL.
Defaults      editor=/usr/bin/nano, !env_editor

设置示例

要为某个用户可以执行所有命令,在配置文件中加入:

用户名   ALL=(ALL) ALL

如果只想允许以某个主机名登录用户执行命令:

用户名   主机名=(ALL) ALL

允许wheel用户组成员无密码使用sudo:

%wheel      ALL=(ALL) NOPASSWD: ALL

要不询问某个用户的密码:

Defaults:USER_NAME      !authenticate
警告: 任何以您的用户名运行的程序都可以无需密码就执行 sudo。

只为用户启用部分命令的执行权限:

用户名 主机名=/sbin/halt,/sbin/poweroff,/sbin/reboot,/usr/bin/pacman -Syu
注意: 最后的设置会覆盖前面的设置,所以限定多的配置应该放到配置文件的后面。

只为某个主机名登录用户启用部分命令的执行权限,不用输入密码:

USER_NAME HOST_NAME= NOPASSWD: /usr/bin/halt,/usr/bin/poweroff,/usr/bin/reboot,/usr/bin/pacman -Syu

更详细的sudoers范例,参见本页。此外,更多信息参见:sudoers 手册

sudoers文件默认权限

sudoers文件的属主和属组ID必须都是0,文件权限位是0440(-r--r-----)。如果你不小心改变了默认权限,应当立即恢复它们:

# chown -c root:root /etc/sudoers
# chmod -c 0440 /etc/sudoers

密码过期时间

用户可以修改sudo记录密码的时间。使用visudo命令将如下内容加入/etc/sudoers

Defaults:用户名 timestamp_timeout=20

对该用户,sudo将记录密码20分钟。时间值也可以是小数。

提示: 如果timestamp_timeout设置为0,sudo总是询问密码。

使用技巧

bash 自动补全支持

详情参见:bash (简体中文)#自定义命令补全

跨终端sudo

警告: 此举使得所有进程都使用同一个sudo任务。

如果不想每次启动新终端都重新输入密码,在配置文件中禁止tty_tickets即可:

Defaults !tty_tickets

环境变量

当前用户的环境变量不会应用到sudo启动的程序,除非使用-E选项:

$ sudo -E pacman -Syu

如果经常需要这样做,可以在~/.bashrc(或其他shell配置文件)中加入命令别名:

alias sudo="sudo -E"

/etc/sudoers中添加以下内容作用相同:

Defaults !env_reset

可以把需要传递环境变量的命令设置到env_keep

Defaults env_keep += "ftp_proxy http_proxy https_proxy no_proxy"

传递命令别名

当前用户的命令别名不会应用到sudo。如果需要这样,只需在~/.bashrc或者/etc/bash.bashrc中加入:

alias sudo='sudo '

使用root密码

默认sudo询问用户密码。添加targetpwrootpw到配置文件的“Defaults”部分,可以让sudo询问root密码:

Defaults targetpw

可以限定特定的组使用 root 密码:

Defaults:%wheel targetpw
%wheel ALL=(ALL) ALL

禁止root登录

警告: ArchLinux用户最好不要禁用root用户,出问题就麻烦大了。

有了sudo,用户也许希望禁止使用root登录。没有了root用户,黑客就不知道管理员账户的名字了。

警告: 务必在禁用root之前配置好其他用户的权限!

使用passwd命令锁住root用户:

# passwd -l root

下列命令解锁root用户:

$ sudo passwd -u root

或者,编辑/etc/shadow文件,将root的加密口令列替换为“!”:

root:!:12345::::::

要再次启用sudo,重新设置其密码即可:

$ sudo passwd root
提示: 要在禁用 root 账号后使用交互 root 身份确认,请使用 sudo -i.

kdesu

KDE下常用 kdesu 以 root 权限执行图形程序。默认情况下,即使root账户被禁用,kdesu仍会尝试使用su切换root。需要配置kdesu以使用sudo,创建/编辑~/.config/kdesurc,加入:

[super-user-command]
super-user-command=sudo

或者使用下面命令:

$ kwriteconfig5 --file kdesurc --group super-user-command --key super-user-command sudo

让 sudo 使用 /etc/sudoers.d 中的文件

sudo 可以解析 /etc/sudoers.d/ 目录中的文件,这样就不需要编辑单一的 /etc/sudoers 文件,可以单独修改一个设置然后放入此目录。目录中配置的格式和 /etc/sudoers一样, 优点包括:

  • 不需要编辑 {ic|sudoers.pacnew}} 文件;
  • 如果新配置有问题,可以删除这个文件而不用编辑 /etc/sudoers.

/etc/sudoers.d/ 目录中的文件是按字母顺序加载的,.~ 开头的文件会被跳过。文件名应该以双字母开头,例如 01_foo,请注意配置文件的顺序以避免相互覆盖。

+

警告: The files in /etc/sudoers.d/ are just as fragile as /etc/sudoers itself: any improperly formatted file will prevent sudo from working. Hence, for the same reason it is strongly advised to use visudo

编辑文件

sudo -esudoedit 可以实现用其它用户编辑文件,但是文件编辑器本身还是以当前用户运行。

这样可以不已 root 用户运行程序,但是保存时具有 root 权限,详情参考 sudo(8) § e.

可以用 meld 管理 pacnew 文件:

$ SUDO_EDITOR=meld sudo -e /etc/file{,.pacnew}

疑难解答

SSH TTY 问题

远程执行命令时,SSH默认不会分配tty。没有tty,sudo就无法在获取密码时关闭回显。使用-tt选项强制SSH分配tty。

另一方面,sudoers中的Defaults选项requiretty要求只有拥有tty的用户才能使用sudo。可以通过visudo编辑配置文件,禁用这个选项:

# Disable "ssh hostname sudo <cmd>", because it will show the password in clear text. 
# You have to run "ssh -t hostname sudo <cmd>".
#
# Defaults    requiretty

权限 Umask

Sudo 会统一用户的 umask 值和它自己的 umask (默认是 0022)。这会阻止 sudo 创建比该用户的 umask 允许的打开权限更多的文件。这默认是合理的,因为没有使用自定义 umask。但是这可能导致用sudo运行一个命令和root运行一个命令建立的文件权限不同。如果这导致了问题,sudo 提供了一个方法来修复 umask,即使想要的 umask 比用户指定的 umask 权限还要多。添加下面内容 (使用 visudo) 会覆盖 sudo 的默认行为:

Defaults umask = 0022
Defaults umask_override

这会将 sudo 的 umask 设置为 root 的默认 umask (0022),覆盖掉默认行为,无论用户的umask设置成什么都会使用这里设定的值。

默认 skeleton 文件

此页面 列出了所有可用配置。