简介
特权分离是 Linux 和类 Unix 操作系统中实施的基本安全范例之一。普通用户以有限权限操作,以减少其影响范围仅限于其自身环境,而不是更广泛的操作系统。
一个名为 root 的特殊用户拥有 超级用户 权限。这是一个没有普通用户限制的管理账户。用户可以以多种不同的方式以超级用户或 root 权限执行命令。
在本文中,我们将讨论如何正确且安全地获取 root 权限,特别关注编辑 /etc/sudoers
文件。
我们将在 Ubuntu 20.04 服务器上完成这些步骤,但大多数现代 Linux 发行版,如 Debian 和 CentOS,应该以类似的方式操作。
本指南假定您已经完成了此处讨论的初始服务器设置。以常规非 root 用户身份登录到服务器,然后继续以下操作。
如何获取 Root 权限
有三种基本方法可以获取 root 权限,它们在复杂程度上有所不同。
以 Root 用户身份登录
获取 root 权限的最简单和最直接的方法是直接以 root 用户登录到服务器。
如果您正在登录到本地计算机(或在虚拟服务器上使用带外控制台功能),在登录提示符处输入 root
作为用户名,然后在要求时输入 root 密码。
如果您通过 SSH 登录,请在 SSH 连接字符串中的 IP 地址或域名之前指定 root 用户:
ssh root@server_domain_or_ip
如果您尚未为 root 用户设置 SSH 密钥,请在提示时输入 root 密码。
使用 su
切换为 Root 用户
直接以 root 用户登录通常不建议,因为很容易开始将系统用于非管理任务,这是危险的。
获得超级用户权限的下一种方法允许您在需要时随时成为 root 用户。
我们可以通过调用 su
命令来实现这一点,su
代表 “substitute user”。要获取 root 权限,请输入:
su
然后会提示您输入 root 用户的密码,之后您将进入一个 root shell 会话。
完成需要 root 权限的任务后,通过输入以下内容返回到正常 shell:
exit
使用 sudo
以 Root 用户身份执行命令
我们将讨论的最后一种获取 root 权限的方法是使用 sudo
命令。
sudo
命令允许您以 root 权限执行一次性命令,而无需生成新的 shell。执行方式如下:
sudo command_to_execute
与 su
不同,sudo
命令将请求 当前 用户的密码,而不是 root 密码。
由于其安全性影响,sudo
访问默认情况下不会授予用户,并且必须在其正常运行之前进行设置。查看我们的 Ubuntu 和 CentOS 的 如何创建新的启用 sudo 的用户 快速入门教程,了解如何设置 sudo
启用用户。
在接下来的部分,我们将更详细地讨论如何修改 sudo
配置。
什么是 Visudo?
sudo
命令通过位于 /etc/sudoers
的文件进行配置。
由于 /etc/sudoers
文件中的不正确语法可能导致系统损坏,从而无法获取提升的权限,因此使用 visudo
命令编辑文件非常重要。
visudo
命令打开一个像普通文本编辑器一样的文本编辑器,但在保存时会验证文件的语法。这可以防止配置错误阻止 sudo
操作,而这可能是您获取 root 权限的唯一方式。
传统上,visudo
使用 vi
文本编辑器打开 /etc/sudoers
文件。但是,Ubuntu 已经配置 visudo
使用 nano
文本编辑器。
如果您想将其更改回 vi
,请发出以下命令:
sudo update-alternatives --config editor
有 4 个选择可用于替代编辑器(提供 /usr/bin/editor)。 选择 路径 优先级 状态 ------------------------------------------------------------ * 0 /bin/nano 40 自动模式 1 /bin/ed -100 手动模式 2 /bin/nano 40 手动模式 3 /usr/bin/vim.basic 30 手动模式 4 /usr/bin/vim.tiny 10 手动模式 按 <enter> 保留当前选择[*],或键入选择编号:
选择对应于您想要进行的选择的编号。
在 CentOS 上,您可以通过将以下行添加到 ~/.bashrc
来更改此值:
export EDITOR=`which name_of_editor`
源文件以实施更改:
. ~/.bashrc
配置了 visudo
后,执行以下命令以访问 /etc/sudoers
文件:
sudo visudo
如何修改 Sudoers 文件
您将在所选的文本编辑器中看到 /etc/sudoers
文件。
我已经从 Ubuntu 20.04 复制并粘贴了该文件,删除了注释。CentOS 的 /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 行
最后一行乍一看可能像是注释:
. . . #includedir /etc/sudoers.d
它确实以 #
开头,通常表示注释。但是,这行实际上表示将在 /etc/sudoers.d
目录中的文件也被引用和应用。该目录中的文件遵循与 /etc/sudoers
文件本身相同的规则。任何不以 ~
结尾且没有 .
的文件都将被读取并附加到 sudo
配置中。
这主要用于应用程序在安装时修改 sudo
权限。将所有相关规则放在 /etc/sudoers.d
目录中的单个文件中,可以轻松查看哪些权限与哪些帐户关联,并且可以轻松地撤消凭据,而无需尝试直接操作 /etc/sudoers
文件。
与 /etc/sudoers
文件本身一样,您应该始终使用 visudo
编辑 /etc/sudoers.d
目录中的文件。编辑这些文件的语法将是:
sudo visudo -f /etc/sudoers.d/file_to_edit
如何给用户赋予 Sudo 权限
用户在管理 sudo
权限时最常见的操作是授予新用户一般的 sudo
访问权限。如果您想要给一个帐户完全的管理访问权限,这将非常有用。
在设置了通用目的管理组的系统上,比如本指南中的 Ubuntu 系统,最简单的方法实际上是将相关用户添加到该组中。
例如,在 Ubuntu 20.04 上,sudo
组具有完整的管理员权限。我们可以通过将用户添加到该组来授予用户相同的权限:
sudo usermod -aG sudo username
也可以使用 gpasswd
命令:
sudo gpasswd -a username sudo
这两种方法都可以实现相同的效果。
在 CentOS 上,通常是 wheel
组而不是 sudo
组:
sudo usermod -aG wheel username
或者,使用 gpasswd
:
sudo gpasswd -a username wheel
在 CentOS 上,如果立即将用户添加到组中不起作用,您可能需要编辑 /etc/sudoers
文件以取消注释组名称:
sudo visudo
. . . %wheel ALL=(ALL) ALL . . .
如何设置自定义规则
现在我们已经熟悉了文件的一般语法,让我们创建一些新规则。
如何创建别名
sudoers
文件可以通过使用各种类型的“别名”更轻松地组织。
例如,我们可以创建三个不同的用户组,其成员有重叠:
. . . User_Alias GROUPONE = abby, brent, carl User_Alias GROUPTWO = brent, doris, eric, User_Alias GROUPTHREE = doris, felicia, grant . . .
组名必须以大写字母开头。然后,我们可以创建规则允许GROUPTWO
的成员更新apt
数据库,规则如下:
. . . GROUPTWO ALL = /usr/bin/apt-get update . . .
如果我们没有指定要作为哪个用户/组运行,如上所示,sudo
默认为 root 用户。
我们可以创建一个“命令别名”,并在GROUPTHREE
的规则中使用它,以允许GROUPTHREE
的成员关闭和重启机器:
. . . Cmnd_Alias POWER = /sbin/shutdown, /sbin/halt, /sbin/reboot, /sbin/restart GROUPTHREE ALL = POWER . . .
我们创建了一个名为POWER
的命令别名,其中包含关闭和重启机器的命令。然后我们允许GROUPTHREE
的成员执行这些命令。
我们还可以创建“Run as”别名,它可以替换规则中指定要以哪个用户执行命令的部分:
. . . Runas_Alias WEB = www-data, apache GROUPONE ALL = (WEB) ALL . . .
这将允许GROUPONE
的任何成员以www-data
用户或apache
用户的身份执行命令。
请记住,当两个规则之间存在冲突时,后面的规则将覆盖前面的规则。
如何锁定规则
有许多方法可以更好地控制sudo
对调用的反应。
与mlocate
软件包相关联的updatedb
命令在单用户系统上相对无害。如果我们希望允许用户以 root 权限执行它而无需输入密码,我们可以创建如下规则:
. . . GROUPONE ALL = NOPASSWD: /usr/bin/updatedb . . .
NOPASSWD
是一个“标签”,表示不会请求密码。它有一个伴随的命令叫做 PASSWD
,这是默认行为。标签对于规则的其余部分是相关的,除非在后续规则中被它的“双胞胎”标签覆盖。
例如,我们可以有如下行:
. . . GROUPTWO ALL = NOPASSWD: /usr/bin/updatedb, PASSWD: /bin/kill . . .
另一个有用的标签是 NOEXEC
,它可以用于阻止某些程序中的危险行为。
例如,一些程序,比如 less
,可以通过在其界面内输入以下内容来生成其他命令:
!command_to_run
这基本上以与less
相同权限执行用户给出的任何命令,这可能非常危险。
为了限制这一点,我们可以使用如下行:
. . . username ALL = NOEXEC: /usr/bin/less . . .
其他信息
在处理sudo
时,还有一些信息可能会有用。
如果在配置文件中指定了要“以其身份运行”的用户或组,您可以分别使用 -u
和 -g
标志以这些用户的身份执行命令:
sudo -u run_as_user command sudo -g run_as_group command
为了方便起见,默认情况下,sudo
会在一个终端中保存您的身份验证详细信息一段时间。这意味着在该计时器到期之前,您不必再次输入密码。
出于安全目的,如果您希望在完成运行管理命令时清除此计时器,您可以运行:
sudo -k
另一方面,如果您想“激活”sudo
命令,以便以后不会提示,或者更新您的sudo
租约,您可以随时输入:
sudo -v
您将被提示输入密码,该密码将被缓存以供以后的sudo
使用,直到sudo
时间段到期。
如果您只是想知道为您的用户名定义了什么样的权限,您可以输入:
sudo -l
这将列出适用于您的用户的/etc/sudoers
文件中的所有规则。这让您对作为任何用户使用sudo
时将被允许或不允许做什么有一个很好的概念。
有许多时候,您会执行一个命令,但由于忘记使用sudo
作为前缀,它会失败。为了避免不得不重新输入命令,您可以利用一个bash功能,即“重复上一个命令”:
sudo !!
双感叹号将重复上一个命令。我们在前面加上sudo
,以便快速将非特权命令更改为特权命令。
作为一些有趣的事情,您可以使用visudo
将以下行添加到您的/etc/sudoers
文件中:
sudo visudo
. . . Defaults insults . . .
这将导致当用户为sudo
输入不正确的密码时,sudo
会返回一个愚蠢的侮辱。我们可以使用sudo -k
来清除之前sudo
缓存的密码来尝试它:
sudo -k sudo ls
[sudo] password for demo: # 在这里输入一个不正确的密码以查看结果 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 权限执行的命令的作用。不要轻视这份责任。学会最佳地运用这些工具来满足您的使用场景,并锁定任何不必要的功能。