如何编辑 sudoers 文件

介绍

特权分离是在Linux和类Unix操作系统中实施的基本安全范例之一。普通用户以有限权限操作,以减少其影响范围仅限于其自己的环境,而不是更广泛的操作系统。

A special user, called root, has super-user privileges. This is an administrative account without the restrictions that are present on normal users. Users can execute commands with super-user or root privileges in a number of different ways.

在本文中,我们将讨论如何正确和安全地获取root权限,特别关注编辑/etc/sudoers文件。

我们将在Ubuntu 20.04服务器上完成这些步骤,但大多数现代Linux发行版,如Debian和CentOS,应该以类似的方式操作。

本指南假定您已经完成了在此处讨论的初始服务器设置。以普通非root用户登录服务器,然后继续以下步骤。注意:本教程深入介绍了特权升级和sudoers文件。如果您只想向用户添加sudo权限,请查看我们的如何创建新的启用sudo的用户快速入门教程,适用于UbuntuCentOS

注意:本教程深入探讨了权限提升和sudoers文件。如果您只想为用户添加sudo权限,请查看我们的如何在Ubuntu和CentOS上创建新的具有sudo权限的用户快速入门教程。

如何获取root权限

获取root权限有三种基本方法,它们在复杂程度上有所不同。

以root身份登录

获取root权限最简单、最直接的方法是直接以root用户身份登录到您的服务器。

如果您正在登录本地机器(或使用虚拟服务器上的带外控制台功能),在登录提示符处输入root作为用户名,并在询问时输入root密码。

如果你是通过SSH登录,需要在SSH连接字符串中在IP地址或域名之前指定root用户:

  1. ssh root@server_domain_or_ip

如果你还没有为root用户设置SSH密钥,那么在提示时输入root密码。

使用su成为root

直接以root身份登录通常是不推荐的,因为很容易开始使用系统进行非管理任务,这是危险的。

下一个获得超级用户权限的方法允许你在需要时随时成为root用户。

我们可以通过调用su命令来实现这一点,该命令代表“替代用户”。要获得root权限,请输入:

  1. su

系统会提示你输入root用户的密码,之后,你将被放入一个rootshell会话中。

当你完成需要root权限的任务后,通过输入以下命令返回到你的正常shell:

  1. exit

使用sudo以root身份执行命令

我们将讨论的获取root权限的最后一种方法是使用sudo命令。

sudo命令允许您以root权限执行一次性命令,而无需生成新的shell。它是这样执行的:

  1. sudo command_to_execute

su不同,sudo命令将请求当前用户的密码,而不是root密码。

由于其安全影响,sudo访问默认不会授予用户,必须在它正确工作之前进行设置。查看我们的如何创建新的具有sudo权限的用户快速入门教程,了解如何在UbuntuCentOS上设置具有sudo权限的用户。

在下面的部分中,我们将更详细地讨论如何修改sudo配置。

什么是Visudo?

sudo命令通过位于/etc/sudoers的文件进行配置。

警告:切勿使用普通文本编辑器编辑此文件!始终使用visudo命令代替!

由于在/etc/sudoers文件中不当的语法可能导致系统损坏,无法获得提升的权限,因此使用visudo命令编辑该文件非常重要。

visudo命令像平常一样打开文本编辑器,但在保存时验证文件的语法。这可以防止配置错误阻止sudo操作,这可能是您获得root权限的唯一方式。

传统上,visudo使用vi文本编辑器打开/etc/sudoers文件。然而,Ubuntu已经配置visudo使用nano文本编辑器。

如果您想将其改回vi,请执行以下命令:

  1. sudo update-alternatives --config editor
Output
There are 4 choices for the alternative editor (providing /usr/bin/editor). Selection Path Priority Status ------------------------------------------------------------ * 0 /bin/nano 40 auto mode 1 /bin/ed -100 manual mode 2 /bin/nano 40 manual mode 3 /usr/bin/vim.basic 30 manual mode 4 /usr/bin/vim.tiny 10 manual mode Press <enter> to keep the current choice[*], or type selection number:

选择与您想要做出的选择相对应的数字。

在CentOS上,您可以通过在~/.bashrc中添加以下行来更改此值:

  1. export EDITOR=`which name_of_editor`

源文件以实施更改:

  1. . ~/.bashrc

配置好visudo后,执行命令以访问/etc/sudoers文件:

  1. sudo visudo

如何修改Sudoers文件

您将在所选的文本编辑器中看到/etc/sudoers文件。

I have copied and pasted the file from Ubuntu 20.04, with comments removed. The CentOS /etc/sudoers file has many more lines, some of which we will not discuss in this guide.

/etc/sudoers
Defaults        env_reset
Defaults        mail_badpass
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

root    ALL=(ALL:ALL) ALL

%admin ALL=(ALL) ALL
%sudo   ALL=(ALL:ALL) ALL

#includedir /etc/sudoers.d

让我们来看看这些行是做什么的。

默认行

第一行,Defaults env_reset,将终端环境重置为清除任何用户变量。这是一种安全措施,用于清除可能有害的环境变量,从sudo会话中清除。

第二行,Defaults mail_badpass,告诉系统将sudo密码尝试失败的通知邮件发送到配置的mailto用户。默认情况下,这是root账户。

第三行,以Defaults secure_path=...开头,指定用于sudo操作的PATH(操作系统将在文件系统中查找应用程序的位置)。这可以防止使用可能有害的用户路径。

用户权限行

第四行,规定了root用户的sudo权限,与前面的行不同。让我们来看看不同的字段是什么意思:

  • root ALL=(ALL:ALL) ALL
    第一个字段表示规则将应用于的用户的用户名(root)。

  • root ALL=(ALL:ALL) ALL
    第一个“ALL”表示这条规则适用于所有主机。

  • root ALL=(ALL:ALL) ALL
    这个“ALL”表示root用户可以以所有用户的身份运行命令。

  • root ALL=(ALL:ALL) ALL
    这个“ALL”表示root用户可以以所有组的身份运行命令。

  • root ALL=(ALL:ALL) ALL
    最后一个“ALL”表示这些规则适用于所有命令。

这意味着我们的root用户可以使用sudo运行任何命令,只要他们提供自己的密码。

组特权行

接下来的两行类似于用户特权行,但它们指定了sudo规则的组。

%开头的名称表示组名。

在这里,我们看到admin组可以在任何主机上以任何用户的身份执行任何命令。同样,sudo组具有相同的权限,但也可以以任何组的身份执行。

包含/etc/sudoers.d行

最后一行乍一看可能看起来像是一个注释:

/etc/sudoers
. . .

#includedir /etc/sudoers.d

它确实以#开头,这通常表示注释。然而,这条线实际上表明,位于/etc/sudoers.d目录中的文件也将被读取并应用。

该目录中的文件遵循与/etc/sudoers文件本身相同的规则。任何不以~结尾且不包含.的文件都将被读取并附加到sudo配置中。

这主要是为了在安装应用程序时更改sudo权限。将所有相关规则放在/etc/sudoers.d目录中的单个文件中,可以轻松查看哪些权限与哪些帐户相关联,并轻松撤消凭据,而无需直接尝试操作/etc/sudoers文件。

/etc/sudoers文件本身一样,您应该始终使用visudo编辑/etc/sudoers.d目录中的文件。编辑这些文件的语法如下:

  1. sudo visudo -f /etc/sudoers.d/file_to_edit

如何为用户提供sudo权限

用户在管理sudo权限时最常见的操作是授予新用户一般的sudo访问权限。如果您想给一个帐户完全的管理系统访问权限,这是有用的。

在设置有通用管理组(如本指南中的Ubuntu系统)的系统上,实际上最简单的方法是将用户添加到该组。

例如,在Ubuntu20.04上,sudo组具有完全的管理员权限。我们可以通过将他们添加到该组来授予用户相同的权限,如下所示:

  1. sudo usermod -aG sudo username

gpasswd命令也可以使用:

  1. sudo gpasswd -a username sudo

这两者都将实现相同的效果。

在CentOS上,通常是wheel组而不是sudo组:

  1. sudo usermod -aG wheel username

或者,使用gpasswd

  1. sudo gpasswd -a username wheel

在CentOS上,如果将用户添加到组中没有立即生效,您可能需要编辑/etc/sudoers文件以取消注释组名:

  1. sudo visudo
/etc/sudoers
. . .
%wheel ALL=(ALL) ALL
. . .

如何设置自定义规则

现在我们已经熟悉了文件的一般语法,让我们创建一些新规则。

如何创建别名

sudoers文件可以通过使用各种类型的“别名”来更轻松地组织事物。

例如,我们可以创建三个不同的用户组,具有重叠的成员资格:

/etc/sudoers
. . .
User_Alias		GROUPONE = abby, brent, carl
User_Alias		GROUPTWO = brent, doris, eric,
User_Alias		GROUPTHREE = doris, felicia, grant
. . .

组名必须以大写字母开头。然后,我们可以创建一个规则,允许GROUPTWO的成员更新apt数据库,如下所示:

/etc/sudoers
. . .
GROUPTWO	ALL = /usr/bin/apt-get update
. . .

如果我们没有指定运行命令的用户/组,如上所述,sudo默认使用root用户。

我们可以通过创建一个“命令别名”并为GROUPTHREE创建一个规则来允许GROUPTHREE的成员关闭和重启机器,如下所示:

/etc/sudoers
. . .
Cmnd_Alias		POWER = /sbin/shutdown, /sbin/halt, /sbin/reboot, /sbin/restart
GROUPTHREE	ALL = POWER
. . .

我们创建一个名为POWER的命令别名,其中包含关闭和重启机器的命令。然后允许GROUPTHREE的成员执行这些命令。

我们还可以创建“以…身份运行”别名,它可以替换指定执行命令的用户的规则部分:

/etc/sudoers
. . .
Runas_Alias		WEB = www-data, apache
GROUPONE	ALL = (WEB) ALL
. . .

这将允许任何GROUPONE的成员以www-data用户或apache用户身份执行命令。

请记住,当两个规则之间存在冲突时,后面的规则将覆盖前面的规则。

如何锁定规则

有多种方法可以实现对sudo响应调用的更多控制。

mlocate包关联的updatedb命令在单用户系统上相对无害。如果我们想允许用户在不输入密码的情况下以root权限执行它,我们可以创建这样的规则:

/etc/sudoers
. . .
GROUPONE	ALL = NOPASSWD: /usr/bin/updatedb
. . .

NOPASSWD是一个“标签”,意味着不会请求密码。它有一个名为PASSWD的同伴命令,这是默认行为。除非在后面的行中被其“双胞胎”标签覆盖,否则标签对规则的其余部分是相关的。

例如,我们可以有这样的行:

/etc/sudoers
. . .
GROUPTWO	ALL = NOPASSWD: /usr/bin/updatedb, PASSWD: /bin/kill
. . .

另一个有用的标签是NOEXEC,它可以用来防止某些程序中的危险行为。

例如,一些程序,如less,可以通过在其界面内输入以下内容来启动其他命令:

!command_to_run

这基本上是以less运行时的相同权限执行用户给出的任何命令,这可能非常危险。

为了限制这一点,我们可以使用这样的行:

/etc/sudoers
. . .
username	ALL = NOEXEC: /usr/bin/less
. . .

其他信息

在处理sudo时,还有一些可能有用的信息。

如果在配置文件中指定了用户或组以“运行身份”,则可以使用-u-g标志分别以这些用户身份执行命令:

  1. sudo -u run_as_user command
  2. sudo -g run_as_group command

为了方便,默认情况下,sudo会在一个终端中保存您的身份验证详细信息一段时间。这意味着在计时器到期之前,您不需要再次输入密码。

出于安全考虑,如果您希望在完成运行管理命令后清除这个计时器,可以运行:

  1. sudo -k

另一方面,如果您想“预热”sudo命令,以便稍后不会被提示,或者续订您的sudo租约,您可以随时输入:

  1. sudo -v

系统会提示您输入密码,该密码将被缓存,以便在sudo时间框架到期之前用于后续的sudo使用。

如果您只是想知道您的用户名定义了哪些权限,您可以输入:

  1. sudo -l

这将列出/etc/sudoers文件中适用于您的用户的所有规则。这为您提供了一个很好的想法,即作为任何用户,您将能够或不能使用sudo做什么。

有很多时候,您会执行一个命令,但由于忘记在前面加上sudo而导致失败。为了避免不得不重新输入命令,您可以利用bash功能,这意味着“重复最后一个命令”:

  1. sudo !!

双感叹号将重复最后一个命令。我们在前面加上了sudo,以快速将无特权的命令更改为有特权的命令。

为了好玩,您可以使用visudo将以下行添加到您的/etc/sudoers文件中:

  1. sudo visudo
/etc/sudoers
. . .
Defaults	insults
. . .

这将导致当用户输入错误的sudo密码时,sudo返回一个愚蠢的侮辱。我们可以使用sudo -k清除之前缓存的sudo密码来尝试一下:

  1. sudo -k
  2. sudo ls
Output
[sudo] password for demo: # enter an incorrect password here to see the results Your mind just hasn't been the same since the electro-shock, has it? [sudo] password for demo: My mind is going. I can feel it.

结论

您现在应该对如何阅读和修改sudoers文件有一个基本的了解,并对获取root权限的各种方法有所掌握。

记住,超级用户权限不会轻易授予普通用户。你必须明白每个你使用root权限执行的命令的作用。不要轻视这种责任。学会在你的使用场景中最好地使用这些工具,并锁定任何不必要的功能。

Source:
https://www.digitalocean.com/community/tutorials/how-to-edit-the-sudoers-file