我的用例是,我有一个脚本,它可以将我的用户从 sudo 组中删除,然后使用该命令在未来的某个时间点再次添加我at
。
问题是我每次都必须重新启动机器才能使更改生效,第一次是停止成为 sudo 用户,第二次(一旦脚本再次将我添加到 sudo 组)才能再次成为 sudo 用户。
奇怪的是,我的 DE (Cinnamon) 和文件资源管理器 (Nemo) 立即获取了更改,这意味着如果我尝试转到文件管理器并“以 root 身份打开”,如果我运行了脚本并且我被从 sudo 组中移除,我就无法执行此操作。但是如果我进入终端并执行sudo apt update
此操作,除非我重新启动,否则此操作将有效。
目标是有效地反映删除/添加我的用户到 sudo 组,而无需重新启动我的机器。(我说重新启动而不是注销,因为奇怪的是,注销显然不起作用)。
我在网上搜索过,一个解决方案是运行:
sudo service sudo restart
但问题是我收到了错误:Failed to restart sudo.service: Unit sudo.service is masked.
我试图取消屏蔽sudo.service
,但没有任何变化。
信息:我使用的是 Linux Mint 22 和 Cinnamon 6.2.9。Linux 内核:6.8.0-48-generic
编辑:
整个脚本的目标我正在制作一个名为delayed-admin 的
项目的分支。它的作用基本上是将主用户从 sudo 组中删除,这样你就无法执行任何需要sudo
访问权限的操作。然后只有两种方法可以执行需要的命令sudo
:
- 等待将
at
用户重新放入 sudo 组的预定功能(因为当您启动命令时,sudo ./abdicate.sh "now + 3 hours"
您将被锁定在 sudo 之外 3 小时。 - 以这种方式使用该命令,即使您不在 sudo 组中,也会执行
sudo delayed example-command
该命令,但它会按照用户通过配置文件选择的一定延迟执行。example-command
我想要实现的目标:当脚本删除/添加我的用户到 sudo 组时能够丢失/获得 sudo 权限,而无需重新启动我的机器。
为什么需要重新登录
您
/etc/sudoers
最有可能包含这样的一行:正是这一行允许
sudo
组中的用户使用 运行命令sudo
。当您运行sudo
并检查您是否在该sudo
组中时,它不会查阅用户/组数据库,而是检查其自己的进程是否带有此信息。一旦您进入组中的 shell(或其他)sudo
,其所有子进程(包括sudo
您运行的)都将在该组中。有多种方法可以使用更改或更新的组信息启动新进程,但这必须是经过深思熟虑的操作(例如注销并再次登录,或重新启动)。这是设计使然。通过更改用户/组数据库,您无法让已在运行的进程立即更改其对组的分配(从而失去或获得
sudo
访问权限)。下面尝试解决您的根本问题。
另一种方法
这是尝试构建一种机制,允许选定的用户暂时失去其不受限制的 sudo 访问权限。实验性的,几乎没有测试过。使用风险自负。
abdicate-until
使用以下内容创建:并使其可执行(
chmod +x …
)。笔记
/full/path/to/delayed
,请进行相应编辑。date -d
,它已通过 GNU 测试date
。请确保date
您可以sudo
理解-d now
并运行(运行sudo date -d now
并查看是否成功)。我假设您想要此功能的用户当前在
sudo
组中,并且可以使用 运行命令sudo
。作为用户运行:创建相关的目录结构和一个文件,该文件稍后会告诉
sudo
您想要“退位”直到现在(所以实际上还没有)。调用并在最后
sudo visudo
添加此行:保存更改并退出编辑器。如果
visudo
提示您有问题,请不要让它实际更改sudoers
文件。当提示您查看里面的文件时,请不要更改此文件。只有接受更改/etc/abdicate/sudoers.d
后才继续下一步。visudo
旧版本
sudo
无法识别@includedir
,因此请使用#includedir
。(我认为,即使旧版本的sudo
无法识别NOTBEFORE=
,这在我们的机制中也绝对至关重要;如果您的sudo
版本太旧,请中止:不要更改sudoers
,删除/etc/abdicate/
,abdicate-until
因为它们不起作用,所以不要继续这个答案。)sudo
从组中删除用户。用户可以通过调用以下命令自行执行此操作:正如您所知,此更改需要重新登录或执行类似操作。在当前 shell 中,您仍然可以使用文件中的
sudo
because of 。我建议您不要退出此 shell,以防出现问题并且我们的机制对您不起作用。从此 shell 您将能够。仅在验证机制有效后才退出此 shell。%sudo ALL=(ALL:ALL) ALL
sudoers
gpasswd --add "$USER" sudo
在单独的 shell 中,您需要以用户身份重新登录。如果此 shell 已经属于正确的用户,但
id
(未id "$USER"
)显示它仍在sudo
组中,那么您可以执行以下操作:用新 shell 替换该 shell,此时
id
应显示它不在sudo
组中(验证这一点)。这是您将测试解决方案的地方。在新的 shell 中运行:
您无需引用
+2 minutes
。我们的脚本无论如何都会将+2
和作为一个参数传递minutes
给: 。使用您期望的任何语法(严格来说:中可用;它可能与您的 中的相同或不同)。date -d
+2 minutes
date
-d
date
$PATH
sudo
date
$PATH
如果命令成功执行,则用户将无法
sudo
在接下来的两分钟内使用,除非sudo delayed …
,或者 中还有其他条目sudoers
允许用户使用sudo
。记住sudo
使用最后一个匹配项。现在你的工作是:sudoers
并确保没有允许用户执行sudo …
他或她在“退位”状态下不能执行的行。sudo -l
以用户身份运行可能会有用。/full/path/to/delayed
自行创建(或者使用您已有的)。这是一项单独的功能。此答案未实现delayed
,它仅设置sudoers
以便“退位”用户仍可以使用运行它sudo
。在验证机制对用户有效后,您现在可以关闭旧 shell、注销、重新启动或执行其他操作。
at
机制根本不使用。重新访问sudo
得益于sudo
它自己将日期和时间与 中文件中存储的值进行比较/etc/abdicate/sudoers.d/
。用户可以通过调用 来检查该值sudo -l
。该机制支持多用户。其他具有访问权限的用户
sudo
可以通过运行以下命令开始使用该机制:要恢复(显然不是处于“退位”状态):
此后,用户需要重新登录才能真正加入该
sudo
组。删除文件会立即产生后果。删除文件而不先将sudo
用户重新添加到组很可能会锁定用户访问权限;需要 root 的密码(如果有)、另一个 sudoer、以单用户模式启动、启动另一个操作系统(例如从 USB 启动实时 Linux)或使用另一台计算机并在那里安装磁盘才能解决此问题。sudo
pkexec
工作原理
假设用户运行以下程序
sudo
:如上所述,在查询时
sudoers
,sudo
使用最后一个匹配项。在文件@includedir /etc/abdicate/sudoers.d
的最后面sudoers
,对于最后一行有机会匹配的文件的用户,/etc/abdicate/sudoers.d
将是该文件的最后一行(目录中其他文件中的行无论如何都不会与用户名匹配)。该行将如下所示:如果时间不早于 ,
<timestamp>
则该行将匹配,并且它将像%sudo ALL=(ALL:ALL) ALL
对组中的用户那样执行操作sudo
。对于所考虑的用户, 的权力ALL=(ALL:ALL) ALL
现在归因于这最后一行,而不是归因于该%sudo …
行。但是如果时间在 之前
<timestamp>
,那么最后的匹配将在其他行中,或者根本没有匹配。我们已将用户从sudo
组中移除,以使%sudo …
此情况下的行不匹配。用户将不会获得 的权力ALL=(ALL:ALL) ALL
(除非与此答案无关的行匹配并赋予权力;这就是您应该检查的sudoers
原因)。