如何在 Linux 上控制 sudo 访问

在Linux系统中,sudo命令赋予使用者以其他身份(例如root用户)执行命令的权力。sudo还具备精细的权限控制能力,您可以精确地管理哪些用户可以访问root权限,是完全控制还是仅限部分命令,本文将为您详细阐述如何操作。

sudo与Root权限

我们常听到一种略为简化的说法:在Linux中,一切皆文件。 实际上,操作系统中的绝大部分元素,包括进程、文件、目录、套接字以及管道,都通过文件描述符与内核进行通信。 虽然并非所有事物都是文件,但大多数操作系统对象都以类似文件的方式进行处理。在条件允许的情况下,Linux和类Unix操作系统都遵循这一设计原则。

“一切皆文件”的理念对Linux有着深远的影响。 不难理解,文件权限是如何在Linux中成为用户特权和访问控制的重要支柱。 如果您是某个文件或目录(一种特殊的文件)的所有者,您就可以对其执行任意操作,包括编辑、重命名、移动和删除。 您还可以设置文件权限,允许其他用户或用户组读取、修改或执行该文件。 这些权限对所有人都具有约束力。

除了超级用户之外,所有用户都被称为普通用户。而root账户则是拥有特殊权限的账户,不受操作系统中任何对象权限的约束。 root用户可以对任何事物执行任何操作,且几乎可以在任何时间进行。

当然,任何知道root密码的人都可以执行上述操作。 他们可能会恶意破坏,或者无意中造成严重损坏。 实际上,即使是root用户本身也可能因操作失误而造成破坏。 没有人是完美无缺的,root权限可能蕴藏着危险。

因此,目前最佳实践是不以root身份直接登录。 使用普通用户账户登录,并在需要提升权限时,使用sudo临时提升权限。 这通常只需要运行一个命令即可。

sudoers列表

用于编写本文的Ubuntu 18.04.3、Manjaro 18.1.0和Fedora 31系统均已预装了sudo命令。 这并不令人意外。 sudo诞生于20世纪80年代初,已经成为几乎所有发行版中进行超级用户操作的标准方式。

在安装现代发行版时,您在安装过程中创建的用户会被添加到名为sudoers的用户列表中。 这些用户可以使用sudo命令。 拥有sudo权限后,您也可以使用它将其他用户添加到sudoers列表中。

当然,随意分配完整的超级用户身份,或者将权限分配给只有部分或特定需求的用户,都是不谨慎的行为。 sudoers列表允许您指定允许特定用户使用sudo的命令。 这样,您无需给予他们整个系统的控制权,同时又能让他们完成必要的任务。

以其他用户身份执行命令

最初,sudo被称为“超级用户执行”,因为您可以用超级用户的身份执行操作。 现在它的功能已得到扩展,您可以像任何其他用户一样使用sudo来执行命令。为了反映这一新功能,它已被重新命名为“替代用户执行”。

要使用sudo以其他用户身份执行命令,我们需要使用 -u(用户)选项。 在下面的示例中,我们将以用户mary的身份执行whoami命令。 如果您在不使用 -u 选项的情况下使用sudo命令,您将以root身份执行该命令。

当然,由于您正在使用sudo,系统会提示您输入密码。

sudo -u mary whoami

whoami命令的输出结果显示,执行该命令的用户账户是mary。

您可以使用sudo命令以其他用户的身份登录,而无需知道他们的密码。 系统会要求您输入自己的密码。 我们需要使用 -i(登录)选项。

sudo -i -u mary
pwd
whoami
ls -hl
exit

您已成功以mary的身份登录。 mary用户账户的.bashrc.bash_aliases.profile文件会像mary用户账户的所有者本人登录时一样被处理。

命令提示符会发生变化,以反映当前会话是属于用户账户mary的。
pwd命令显示您当前位于mary的主目录
whoami 命令表明您正在使用用户账户mary。
目录中的文件属于mary用户账户。
exit命令将您带回到您原来的用户账户会话

编辑sudoers文件

要将用户添加到可以使用sudo的列表中,您需要编辑sudoers文件。 务必仅使用visudo命令来执行此操作。 visudo命令可以防止多人同时尝试编辑sudoers文件。 它还在您保存文件内容时进行语法检查和解析

如果您的编辑未能通过测试,则文件不会被盲目保存。 您可以选择取消并放弃更改,返回并重新编辑更改,或者强制保存不正确的编辑。 最后一种选择是非常糟糕的,请不要尝试这样做。 您可能会发现自己身处所有人都被意外锁定,无法使用sudo的境地。

尽管您使用visudo命令开始编辑过程,但visudo本身并不是一个编辑器。 它会调用您现有的编辑器之一来执行文件编辑。 在Manjaro和Ubuntu上,执行visudo命令后会启动简洁易用的编辑器 nano。 在Fedora上,visudo会启动功能更强大的Vim编辑器,但Vim编辑器并不那么直观。

如果您更喜欢在Fedora上使用nano,您可以轻松实现。 首先,安装nano:

sudo dnf install nano

然后,必须使用以下命令调用 visudo

sudo EDITOR=nano visudo

这看起来是一个不错的别名候选。 nano编辑器将打开,并加载sudoers文件。

将用户添加到sudo

使用visudo打开sudoers文件。 使用此命令或上述命令来指定您选择的编辑器:

sudo visudo

浏览sudoers文件,直到找到%sudo条目的定义。

百分号表示这是一个组的定义,而不是用户的定义。 在某些发行版中,%sudo行的开头有一个井号#。 这会将该行变成注释。 如果是这种情况,请删除井号并保存文件。

%sudo行的具体含义如下:

  • %sudo:表示组的名称。
  • ALL=:表示此规则适用于该网络上的所有主机。
  • (ALL:ALL):表示该组的成员可以以所有用户和所有组的身份运行命令。
  • ALL:表示该组的成员可以运行所有命令。

稍作调整,该组的成员就可以在此计算机或此网络中的其他任何主机上以任何用户或任何组的身份运行任何命令。 因此,将用户添加到sudo组是一种授予用户root权限以及使用sudo权限的简便方法。

我们有两个用户,Tom和Mary,他们分别拥有用户账户tom和mary。 我们将使用usermod命令将用户账户tom添加到sudo组。 -G(groups)选项指定我们要将tom账户添加到的组。 -a(append)选项将此组添加到用户账户tom已属于的组列表中。如果没有此选项,用户账户tom将被放置在新组中,并从其他任何组中删除。

sudo usermod -a -G sudo tom

让我们查看一下Mary属于哪些组:

groups

用户账户mary仅属于mary组。

让我们查看一下Tom:

groups

tom用户账户(也即Tom)属于tom和sudo组。

现在,我们尝试让Mary执行一些需要sudo权限的操作。

sudo less /etc/shadow

Mary无法查看受限制的文件/etc/shadow的内容。 她因尝试未经许可使用sudo而受到斥责。 让我们看看Tom的表现如何:

sudo less /etc/shadow

Tom在输入他的密码后,即可查看/etc/shadow文件。

只需将Tom加入sudo组,他就被提升为可以不受限制地使用sudo的精英群体。

授予用户有限制的sudo权限

Tom已被赋予完整的sudo权限。 他可以执行root或sudo组中的任何其他成员所能执行的任何操作。 这可能会给他超出您愿意给予的权限。 有时,用户需要执行一些需要root权限的任务,但没有充分的理由让他们拥有完整的sudo访问权限。 您可以通过将它们添加到sudoers文件并列出它们可以使用的命令,来实现这种平衡。

让我们了解一下用户账户harry的所有者Harry。 他不属于sudo组,也没有sudo权限。

groups

Harry能够安装软件是很有用的,但我们不希望他拥有完整的sudo权限。 没问题,我们可以启动visudo

sudo visudo

向下滚动文件,直到超过组定义。 我们将为Harry添加一行。 由于这是一个用户定义而不是组定义,因此我们不需要以百分号开头。

用户账户harry的条目如下:

harry    ALL=/usr/bin/apt-get

请注意,“harry”和“ALL=”之间有一个制表符。

这句话的意思是,用户账户harry可以在连接到该网络的所有主机上使用列出的命令。这里列出的一个命令是“/usr/bin/apt-get”。 我们可以通过将多个命令添加到列表中并以逗号分隔的方式,授予Harry访问多个命令的权限。

将该行添加到sudoers文件中,然后保存该文件。 如果您想仔细检查该行的语法是否正确,我们可以使用-c(仅检查)选项让visudo扫描文件并检查语法:

sudo visudo -c

检查通过,visudo报告一切正常。 Harry现在应该可以使用apt-get安装软件,但如果他尝试使用其他任何需要sudo的命令,都应该被拒绝。

sudo apt-get install finger

Harry已被授予适当的sudo权限,他可以安装该软件。

如果Harry尝试使用需要sudo的不同命令会发生什么呢?

sudo shutdown now

Harry被阻止执行该命令。 我们已成功地授予了他特定的、受限制的访问权限。 他可以使用指定的命令,而不能使用其他命令。

使用sudoers用户别名

如果我们想给Mary相同的权限,我们可以在sudoers文件中为用户账户mary添加一行,就像我们对Harry所做的那样。另一种更简洁的方式是使用User_Alias来实现相同的目的。

sudoers文件中,User_Alias包含了用户账户名称的列表。 然后,您可以在定义中使用User_Alias的名称来表示所有这些用户账户。 如果您想更改这些用户账户的权限,您只需编辑一行即可。

让我们创建一个User_Alias并在我们的sudoers文件中使用它。

sudo visudo

Scroll down in the file until you come to the User_Alias specification line.
   

通过键入以下内容添加User_Alias:

User_Alias INSTALLERS = harry, mary

每个元素之间用空格分隔,而不是制表符。 逻辑分解为:

  • User_Alias: 这告知visudo这将是一个User_Alias。
  • INSTALLERS: 这是此别名的自定义名称。
  • = harry, mary:这是要包含在此别名中的用户列表。

现在,我们将编辑之前为用户账户harry添加的行:

harry    ALL=/usr/bin/apt-get

将其更改为:

INSTALLERS    ALL=/usr/bin/apt-get

这意味着,“INSTALLERS”User_Alias定义中包含的所有用户账户都可以运行apt-get命令。 我们可以用Mary来测试一下,她现在应该可以安装软件了。

sudo apt-get install colordiff

Mary可以安装软件,因为她在“INSTALLERS”User_Alias中,并且该User_Alias已被授予这些权限。

三个快速sudo技巧

当您忘记在命令中添加sudo时,请键入

sudo !!

这将会在上一条命令的开头添加sudo并重复执行。

使用sudo并使用密码进行身份验证后,在15分钟内您无需再与其他sudo命令一起使用密码。 如果您想立即忘记您的身份验证,请使用:

sudo -k

有没有想过在哪里可以看到失败的sudo命令尝试? 它们会记录在/var/log/auth.log文件中。 您可以通过以下方式查看它:

less /var/log/auth.log

我们可以看到用户账户mary的条目,当她尝试以用户“root”身份运行关闭命令时,她在TTY pts/1上登录。

强大的力量……

……伴随着将部分权力委托给其他人的能力。 现在您知道如何有选择地授权其他用户。