我正在编写一个 bash 脚本:
- 在初始化时运行一些 sudoed 命令
- 出于安全目的释放 root 权限 (
sudo -K
) - 运行非特权程序
- 但终止时需要 root 权限
我正在寻找一个避免在脚本终止时再次询问用户密码的简单且安全的方法。
sudo -K
在等待捕获术语信号之前,我正在考虑分叉。我不知道这是否是最优雅/最安全的解决方案。
这是代码:
sudo unshare -m \
sudo -u "$USER" -g `id -g -n "$USER"` \
bash -c \
"sudo mount --bind \"$MOUNT_DIR\" \"$MOUNT_DIR\"; \
sudo mount --make-private \"$MOUNT_DIR\"; \
sudo -K; \
<unprivilegied program here>; \
sudo umount \"$MOUNT_DIR\""
注意:仅供参考,这会在命名空间中创建一个只有程序才能访问的私有挂载。unshare -r
不是运行程序的选项。
答案1
我注意到您在普通用户和根用户之间来回切换:
- 切换到root运行
unshare
- 切换回普通用户来运行
bash
(虽然看起来你没有使用任何bashisms,所以你也可以运行sh
这将更便携并且可能更轻量级) - 在该 shell 内多次切换回 root
bash
以执行更多特权操作
我认为您可以简化此操作并减少需要在用户之间来回切换的次数并同时解决您的问题。
sudo unshare -m sh -c '
mount --bind "$1" "$1";
mount --make-private "$1";
exec sudo -u "#$SUDO_UID" -g "#$SUDO_GID" sh -c "
sudo -K;
<unprivilegied program here>
"
' - "$MOUNT_DIR"
从技术上讲,有一个根 shell 在非特权部分的执行过程中持续运行,但 shell 唯一要做的就是等待非特权部分完成,而不做其他事情。但是,如果您确实想提前放弃sudo
特权并且不必要求用户再次授予它们,那么所有替代方案也将涉及一个等待信号umount
以某种方式运行命令的延迟进程。
顺便说一句,你的命令是独立的,这很好,我在我的建议中保留了这种精神,但说实话,作为命令行选项提供的大块代码很难sh -c
编写、读取和维护,因为您必须担心的引用复杂性,我建议将它们分解到自己的脚本中并将整个过程运行为:
sudo unshare -m /usr/local/bin/script-that-does-the-rest-of-the-work
此外,这样做可以更轻松地为允许的命令编写 sudo 规则,而使用我的建议很难编写这些规则,除非您允许用户运行任何命令,这与授予他们完全 root 访问权限相同。在这种情况下,您必须允许该命令,这编写起来unshare -m sh -c <huge block> "$MOUNT_DIR"
相当具有挑战性。Cmnd_Alias