内容纲要

本文为《Linux & Debian》专栏系列


在执行一些操作的时候可能会遇到权限不够的问题,一种解决思路是「既然当前用户没有权限,就切换成有权限的用户去执行嘛」,所以可以使用 su - 切换到 root 用户再使用 su - <user-name> 切换回普通用户。但 root 毕竟是具有极高权限的用户,流传它的密码且拿到它的人的行为不可控是有安全隐患的。

那么,在需要的时候以 root 身份执行命令,且不需要知道 root 密码的方法会更好,这就是 sudo。

比方说:

ls /root

返回:ls: cannot open directory '/root': Permission denied

这是因为当前我所使用的普通用户没有访问 /root 的权限,此时加上 sudo

sudo ls /root

即表示以 root 用户访问 /root 这时我的普通用户就可以得到正确的返回结果了。

安装 sudo

可能有的 Linux 发行版或者云计算服务商提供的系统默认并不带有 sudo,这时候需要自行安装一下:

# Debian
apt-get install sudo -y
# CentOS
yum install sudo -y

配置 sudo

需要以 root 用户使用 visudo 命令进行配置 sudo,因为它可以验证文件语法以免配置错误

visudo

返回:

#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults        env_reset
Defaults        mail_badpass
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d

以上是 sudo 的配置文件,可以看到一段配置主要是三个部分

root ALL=(ALL:ALL) ALL授权用户/组 主机=[(切换到哪些用户或组)] [是否需要输入密码验证] 命令1,命令2,...

第一部分root%sudo

此处为用户或用户组,行首加有百分号表明是用户组。

第二部分ALL=(ALL:ALL)

首先是等号前的 ALL 表示主机,当仅允许本地登录时使用 localhost 当包括远程登录时使用 All,或是指定主机名如 computer-name

然后是括号里,表示的是切换到的用户或用户组,如果省略, 相当于(root:root),表示可以通过 sudo 提权到 root; 如果为 (ALL) 或者 (ALL:ALL), 表示能够提权到 (任意用户:任意用户组)

第三部分ALL

执行命令时是否需要输入密码,默认为需要,如果不需要则修改为:NOPASSWD: ALL

举几个例子

conners ALL=(ALL:ALL) NOPASSWD: ALL:表示用户名为 conners 的用户可以使用在任何主机上使用 sudo 命令且不需要输入密码

conners localhost=(ALL) NOPASSWD: ALL:表示用户名为 conners 的用户仅在本地主机登录时使用 sudo 命令且不需要输入密码

再或者,假设我们有一个用户 Hattie 是专门用于添加用户管理的操作

hattie ALL=/bin/useradd:表示用户名为 hattie 的用户可以以 sudo 执行程序 /bin/useradd,执行时需要密码(因为没有 NOPASSWD:

上述例子是一个非常好表明 sudo 命令作用的例子:可以在日常一些敏感操作时,只给指定用户执行指定程序且不需要 root 用户密码,由此做到权限管理。

需要注意的是这里程序使用的是绝对路径而不只是名称,此外此处可以使用通配符和排除,比如:

hattie ALL=/usr/sbin/*,/sbin/*,!/usr/sbin/fdisk

还是以 hattie 为例,上述例子表示它可以运行 /usr/sbin//sbin/ 目录下的程序,但不能运行 /usr/sbin/fdisk

💡 提示:如果不知道程序的路径怎么办?可以使用 which 命令,如 which useradd

知道了如何配置后就要修改配置文件了,但官方并不建议直接修改 visudo 后的默认配置文件(也就是 /etc/sudoers),而是指定了目录 /etc/sudoers.d

ls /etc/sudoers.d # 可以先看看有没有预设的文件
# vim /etc/sudoers.d/custom # 或是自行直接在该目录下创建一个配置文件
visudo /etc/sudoers.d/90-cloud-init-users # 比如 Debian 会在该目录下有个文件,我打算直接使用它

💡 提示:在 /etc/sudoers.d/ 内的配置文件生效是因为默认配置中末尾的 #includedir /etc/sudoers.d,由此可知设置其他路径的方法了吧(虽然一般也不会去改)

注意我仍然使用的是官方推荐的 visudo 命令进行配置

为什么我默认就可以使用 sudo 了?

到这里你可能会有疑问:「为什么没有进行配置的情况下我的普通账号直接就可以使用 sudo 命令」,这是因为上述默认配置文件中的一行:

%sudo   ALL=(ALL:ALL) ALL

属于 sudo 用户组的用户可以在任何主机上使用 sudo 命令,使用时需要密码,而你的用户已经在名为 sudo 的用户组中了,可以自行查看一下:

id

返回:

uid=1000(conners) gid=1000(conners) groups=1000(conners),4(adm),20(dialout),21(fax),24(cdrom),25(floppy),26(tape),27(sudo),29(audio),30(dip),44(video),46(plugdev),100(users),109(netdev),114(lpadmin),119(bluetooth),121(scanner)

可以看到 27(sudo)

小结

  1. 使用 sudo 可以在没有 root 用户密码的情况下进行一些敏感操作。
  2. 进一步的,可以仅让指定用户在指定主机上以 root 身份执行指定命令,这样的权限管理相比直接使用 root 用户安全可靠。
  3. 默认情况下拥有 sudo 用户组的用户可以直接使用 sudo 命令,所以也可以直接将现有的用户加入 sudo 用户组。
  4. 如果要修改 sudo 配置,需使用 visudo 命令且在 /etc/sudoers.d/ 目录下自定义配置及配置文件,不建议直接修改 /etc/sudoers
  5. 配置的第一段为用户或用户组,若是用户组则在名称前加百分号。
  6. 配置的第二段为主机名及切换到的用户、用户组,主机名可以是本地(localhost)、指定主机名或所有(ALL),用户或用户组为可选。
  7. 配置第三段为是否需要密码及指定的程序,不需要密码则在该段开头使用 NOPASSWD:,允许所有程序为 ALL,否则填程序的绝对路径,多个程序以逗号隔开,排除的程序在路径开头使用感叹号