问题描述
有哪些可移植选项可以删除 root 权限并以不同于 shell 脚本的用户身份执行给定命令?
What portable options do exist to drop root privileges and execute a given command as a different user from a shell script?
在做了一些研究之后,这里有一些非选项:
After doing a bit of research, here are a few non-options:
su $USER -c "$COMMAND"
使用 PAM 堆栈并创建一个新的 cgroup(在 systemd 下运行时).它也会在用户命名空间中失败,因为审计调用在旧版 Linux 上返回 -EPERM.sudo -u $USER $COMMAND
默认情况下未安装在许多系统上.start-stop-daemon --pidfile/dev/null --start --chuid $USER --startas/bin/sh -- -c "$COMMAND"
很难使用并且仅在 Debian 系统上可用.chpst -u $USER $COMMAND
在许多系统上缺失.runuser -u $USER -- $COMMAND
适用于su
不适用的地方,但需要最新的 util-linux.
su $USER -c "$COMMAND"
uses the PAM stack and creates a new cgroup (when run under systemd). It also fails in user namespaces, because the audit call returns -EPERM on older versions of Linux.sudo -u $USER $COMMAND
is not installed by default on many systems.start-stop-daemon --pidfile /dev/null --start --chuid $USER --startas /bin/sh -- -c "$COMMAND"
is very hard to use and only available on Debian systems.chpst -u $USER $COMMAND
is missing on many systems.runuser -u $USER -- $COMMAND
works wheresu
doesn't, but requires recent util-linux.
推荐答案
如果你想要 POSIX,那么 su
是你唯一的选择(除非你想写一个 C 程序).su
有几个优点(或没有,取决于您的要求):
If it's POSIX you want, then su
is your only option (unless you want to write a C program). su
has several advantages (or not, depending on your requirements):
- 这是一个系统工具,它不会忘记 Linux 3.42 中引入的新咖啡 UID(用于饮用饮料的 UID),并且不会通过在组权限之前删除用户权限或忘记能力.
- 它将权限设置为已知状态:用户 ID、用户和组数据库中该用户的记录组,没有额外的功能.
- 它记录日志条目.
- 再说一次,它是完全标准的,保证在任何地方都可用,但在最坏的系统上.
现在在实践中,有些系统不是 POSIX——比如这个旧的 Linux,它在用户命名空间中失败.他们是休息时间.
Now in practice some systems aren't POSIX — like this older Linux where it fails in user namespaces. Them's the breaks.
如果您想要在实践中具有相当可移植性的东西(在非嵌入式平台上)并且可以为您提供更大的控制权,请使用 Perl(或 Python,安装较少).作为首选,使用可靠的模块:Privilege::Drop.
If you want something that's reasonably portable in practice (on non-embedded platforms) and that gives you a greater decree of control, use Perl (or Python, a bit less commonly installed). For preference, use a solid module: Privilege::Drop.
perl -e 'use Privileges::Drop; drop_uid_gid(123, 456); exec("/path/to/command", "--option", "an argument")'
Privilege::Drop
负责做正确的事情(删除补充组,检查错误).然而,它可能并不完整;例如,它不知道功能.
Privilege::Drop
takes care of doing things right (dropping supplemental groups, checking for errors). It might not be complete, however; for example it isn't aware of capabilities.
如果您必须手动完成,请注意以下几点:
If you must do it by hand, take care of several things:
- 在用户权限之前删除组权限.
- 要删除补充组,请设置
$) = "456 456"
其中 456 是目标 GID ($) = 456
只会设置 EGID 而不会影响补充组组). - 之后检查 (E)[UG]ID 并在失败时中止.
- Drop group privileges before user privileges.
- To drop supplemental groups, set
$) = "456 456"
where 456 is the target GID ($) = 456
would only set the EGID without affecting the supplemental groups). - Check the (E)[UG]ID afterwards and abort on failure.
这篇关于如何从 POSIX shell 脚本中删除 root 权限?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!