我正在设置一台 Ubuntu (10.10) 机器,供多人使用。它是一间小型办公室中的一台共享机器。它的主要作用是使用 VirtualBox 托管虚拟机并使用 Samba 提供文件服务。
对于 Samba,需要设置多个用户帐户,以便不同的人可以从他们自己的工作站连接到 Samba 共享。但是,还有一个专门用于运行虚拟机的帐户,多个人将使用该帐户。有时人们会尝试使用此帐户执行需要提升权限的操作 - 这会导致 Gnome 的“请输入管理用户的密码”对话框弹出。但是,此对话框要求输入我的密码 - 当我设置机器时,我的帐户是第一个创建的帐户,因此它似乎假设我是唯一被授予 sudo 权限的用户。
我想指定另一个用户作为“首选管理员”,但这个用户不能是共享帐户用户,因为每个人都必须知道该帐户的密码,所以我想严格限制其权限。这个用户也不能是我的帐户,因为我绝不会告诉其他人我的密码,而且我也不会经常出现在网站上,无法亲自输入密码。不过,有人能亲自做这件事,所以我把它们添加到了/etc/sudoers
。我怎样才能告诉 Ubuntu,当它需要提升某些权限时,它应该请求他们的先开通账户吗?
总结一下:
- 机器上的帐户:Alice、Bob、Carol、Dave、Eliza。
- 安装 Ubuntu 时,Alice 是安装过程中添加的第一个用户。
/etc/sudoers
“Dave”实际上是一个许多人使用的账户,但由于其密码是公开的,因此许多人无法登录。- Bob 已在 Gnome 中被设置为“管理”帐户,并且已正确输入
/etc/sudoers
- Bob 是这个办公室的老板。 - 当以 Bob、Carol、Eliza 或 Dave 身份登录并尝试执行需要提升权限的操作时,系统应请求 Bob 的凭据。
- 当以 Alice 身份登录并尝试执行需要提升权限的操作时,系统应该请求 Alice 的凭据(尽管 Alice 有点像一个粗野的系统管理员,并且习惯于使用它
su -
来执行扩展的管理任务)。
我需要进行哪些配置更改才能达到所需的状态?
答案1
首先要指出的是,特权行动是允许的非根用户通过两种不同的机制。
sudo
PolicyKit
第一个用于当你明确地运行带有命令的命令sudo
或带有命令包装的菜单项时gksu
(例如Synaptic 软件包管理器)。
在这种情况下,所需的密码是调用用户的密码,通常是登录用户的密码。
第二种方法用于 PolicyKit 感知应用程序尝试执行特权操作时。在这种情况下,应用程序会询问 PolicyKit 本地机构(通过 D-Bus)是否可以执行该操作。然后,本地机构通过身份验证代理要求活动用户证明其身份。对话框窗口如下所示(不幸的是,文本是意大利语 :)
您可以通过小黑三角形和标签识别 PolicyKit细节。如您所见,如果组中有多个用户admin
,您可以从列表中选择使用哪个用户进行身份验证。
考虑到所有这些,sudo
就可实现的配置而言,和 PolicyKit 都要复杂得多:您可以配置无需密码即可执行的操作、仅由特定用户或组执行的操作等。
回到你的问题,当应用程序使用的机制是 PolicyKit 时,无论当前登录的用户如何,所需的密码都是 Bob 或 Alice 的密码(如果我理解正确的话,这是仅有的两个管理员用户),你可以从列表中更改你想要用于身份验证的用户。
当应用程序使用的机制是sudo
(对于通过 GUI 执行的管理任务,这种情况变得越来越不常见)时,您没有立即和简单的方法来选择用户进行身份验证。
答案2
显然,sudo
在这种情况下,这将是我的首选。主要问题似乎是大多数(实际)管理员实际上并没有/etc/sudoers
充分利用它(User_Alias
、Runas_Alias
、Host_Alias
、Cmnd_Alias
)。
大多数管理员最终只使用了部分现存的规则并添加用户,或者更糟的是,只是将用户添加到sudo
通常存在 Ubuntu 设置规则的组中 ( %sudo
...)。当然,这赋予了各个用户自由支配和超级用户帐户的全部权力。
鉴于您的评论:
所以我把它们添加到
/etc/sudoers
我估计你也尽量不要使用它。
在像您这样的场景中,我会逐字逐句地编写一些限制 Bob 的操作。事实上,这是我在我维护的服务器上所做的,以允许两个特定用户重新启动主机上的特定 KVM 客户机。脚本将包含一个带有解释器绝对路径的 hashbang(例如,#!/bin/dash
而不是#!/usr/bin/env bash
),并且可能使用在其他地方用于特权任务的 shell(/bin/dash
或/bin/sh
)。这些只是预防措施。除此之外,我会确保将所有绝对路径硬编码到二进制文件,并尽可能少地使用它们。例如,当使用bash
/dash
时,我更喜欢builtin
s 而不是command
s(参见man bash
)。您可以通过为变量分配绝对路径并根据该变量引用程序($VIRSH
而不是/usr/bin/virsh
)来使其易于维护。如果可以,请在调用任何外部脚本之前审查其代码。特别是如果您需要在特权上下文中调用它们。在我的例子中,我还将用户限制在特定的根目录和特定的 SSH 子系统中,因为他们仅通过公钥身份验证连接到机器sshd
。显然你不需要那样做。
确保chown root: <the-script>; chmod u=rw,a=,a+rx <the-script>
防止任何非root
专业人士对其进行修改。还要注意目标二进制文件上启用的setuid
和setgid
位(find
可用于发现它们)。我们暂时假设您的脚本位于/usr/sbin/priv-action
。
现在编辑你的/etc/sudoers
。noexec
也可以用来阻止除明确允许的二进制文件之外的其他二进制文件。 实际上还有很多其他设置,不仅仅是我在这里描述的那些。 因此请务必查阅man sudoers
。
现在我更喜欢在我的文件中命名用户(User_Alias
)sudoers
,但您也可以使用Group_Alias
(man sudoers
)或实际的系统组(例如%sudo
):
# The list is comma-separated: bob,alice,...
User_Alias LIMITED_ADMINS=bob
然后添加命令别名以允许执行该特定脚本:
# The list is comma-separated: /usr/sbin/priv-action,/bin/bash,...
Cmnd_Alias PRIV_ACTION=/usr/sbin/priv-action
最后但并非最不重要的是允许bob
(或者更确切地说,下面列出的用户LIMITED_ADMINS
)通过脚本执行特权命令的神奇行:
LIMITED_ADMINS ALL=(root) PRIV_ACTION
与之前的别名定义不同,该行需要解释。因此,让我们首先深入了解“用户规范”行中各部分的含义。以下是man sudoers
帮助:
用户规范的基本结构是
who where = (as_whom) what
。
示例行(在大多数 Ubuntu 设置中可以找到):
root ALL=(ALL) ALL
这说明用户命名 root
(用于#0
将其绑定到 UID 0
)可以在所有主机上在任何用户上下文中运行,但会要求输入密码(假设默认行为)。NOPASSWD
在最后一个标签之前添加标签ALL
也可以允许root
执行相同操作而无需输入密码(如下所示root ALL=(ALL) NOPASSWD:ALL
:)。ALL
是各种别名类型的内在通配符别名。
回到鲍勃的话题:
LIMITED_ADMINS ALL=(root) PRIV_ACTION
将允许bob
和 的其他列出的成员以用户(暗示为组,但可以指定,请参阅)User_Alias LIMITED_ADMINS
身份运行中给出的命令(在所有主机上,这就是 的用途) 。它会变得更好。仍然假设您编写此脚本,您可以允许各种参数,从而避免编写多个脚本。很乐意采用类似 shell 的通配符来限制允许传递的参数的可能性。ALL
root
man sudoers
Cmnd_Alias PRIV_ACTION
/etc/sudoers
我一直发现管理员并没有按照sudoers
应该的方式使用它,这就是为什么我很欣赏《Linux Server Hacks》和《Linux Server Hacks Volume Two》这两本书中各自的“Hack”,它让我开始更复杂地使用这个伟大的功能。
你可以想出各种复杂的——这可能对安全方面没有多大帮助——针对你特定情况的解决方案,但是一旦你掌握了基本的词汇,你/etc/sudoers
就可以完成相当神奇的壮举:)
注意:/etc/sudoers.d/
如果您愿意,也可以在下面创建一个新文件。假设您的文件/etc/sudoers
包含以下行:
#includedir /etc/sudoers.d
答案3
Unix/Linux 中只有一个超级用户,其名称为 root,但 sudoers 是可以成为 root 的用户。您应该使用组:
newgrp admins
然后将用户分配到该组:
chgrp alice admins
然后将管理员组添加到 sudoers 配置文件中,就像该组是用户一样。
更新
或者您可以将任何用户添加到管理员组:
chgrp alice admin