我无法弄清楚如何禁用任何命令的 shell 转义,以便我可以(这是一个示例!)执行以下操作:
sudo-user ALL=(ALL) NOEXEC: NOPASSWD: ALL
sudoers 手册是这样说的:
一个命令可能有零个或多个与其关联的标签。有八个可能的标记值:NOPASSWD、PASSWD、NOEXEC、EXEC、SETENV、NOSETENV、LOG_INPUT、NOLOG_INPUT、LOG_OUTPUT 和 NOLOG_OUTPUT。一旦在 Cmnd 上设置了标签,Cmnd_Spec_List 中的后续 Cmnd 就会继承该标签,除非它被相反的标签覆盖(即:PASSWD 覆盖 NOPASSWD,NOEXEC 覆盖 EXEC)
但这并没有描述如何设置多个标志。使用逗号似乎不起作用(它将第二个标签视为别名)
更好的是,我想设置一个默认值,所以上面的行是:
defaults NOEXEC
sudo-user ALL=(ALL) NOPASSWD: ALL
我知道 sudo 可以使用 noexec 进行编译,但在这种情况下这是不切实际的。我也知道这不是全部答案 - 可以通过适当设置 LD_PRELOAD 来颠覆,但这是一个开始。
须藤版本:
Sudo version 1.8.19p2
Sudoers policy plugin version 1.8.19p2
Sudoers file grammar version 45
Sudoers I/O plugin version 1.8.19p2
On RHEL 7.5
答案1
不要这样做。
您赋予sudo-user
以任何用户身份运行任何命令的能力。这包括修改的能力 /etc/sudoers
使用任何不需要执行子流程的工具。您可能认为排除visudo
,但严格来说,您没有需要 visudo
编辑/etc/sudoers
。
例如:
sudo-user$ sudo sed --in-place -e '/^sudo-user/s/NOEXEC://' /etc/sudoers
...并且用户刚刚删除了NOEXEC:
限制。
用户可以随意解除的限制并不是真正的限制。
另外,NOEXEC:
可能会导致问题。它不仅可以防止 shell 转义:它还可以防止使用sudo
from执行的程序直接启动任何其他程序。这可能会产生很多后果。
例如,如果您sudo-user
停止并稍后重新启动cron
守护程序(例如,在某些维护期间停止计划作业),则重新启动的cron
守护程序将由于限制而无法实际执行任何计划作业NOEXEC:
。
NOEXEC:
存在,以便系统管理员可以将其应用于精心选择的程序,这些程序被发现能够执行其任务而无需exec()
任何子进程。盲目地应用到一切会引起问题。
但如果你绝对必须这么做,那么方法如下。
从sudoers(5)
手册页:
User specification
User_Spec ::= User_List Host_List '=' Cmnd_Spec_List \
(':' Host_List '=' Cmnd_Spec_List)*
Cmnd_Spec_List ::= Cmnd_Spec |
Cmnd_Spec ',' Cmnd_Spec_List
Cmnd_Spec ::= Runas_Spec? SELinux_Spec? Tag_Spec* Cmnd
Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'
SELinux_Spec ::= ('ROLE=role' | 'TYPE=type')
Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' |
'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' |
'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' | 'PASSWD:' |
'NOPASSWD:' | 'SETENV:' | 'NOSETENV:')
这是一个详细的关于如何构造一个的描述用户规范文件的行sudoers
。阅读起来可能有点乏味,但它确实包含了您需要的信息。
让我们使用您的示例行来解决这个问题:
sudo-user ALL=(ALL) NOEXEC: NOPASSWD: ALL
整条生产线被称为用户规范, 或者User_Spec
。
其分解如下:
User_List
您的示例中只有一个用户:sudo-user
Host_List
只有一个条目,ALL
Cmnd_Spec_List
在你的例子中是(ALL) NOEXEC: NOPASSWD: ALL
- 该行上没有其他
: Host_List = Cmnd_Spec_List
单位(括号后的星号表明可能有零个或多个这样的附加单位。)
你的Cmnd_Spec_List
没有逗号,所以它只有一个Cmnd_Spec
。
Cmnd_Spec
分解为:
- 可选
Runas_Spec
:根据您的情况,(ALL)
- 可选的
SELinux_Spec
,它在您的示例中不存在 - 零个或多个
Tag_Spec
s,这是您想了解的部分 Cmnd
,命令,这就是ALL
你的情况。
SingleTag_Spec
只是列出的关键字之一,末尾带有冒号,没有明确列出逗号、空格或其他分隔符。该Cmnd_Spec ::=
行准确地告诉我们在该行的何处放置空格。由于没有说明如何在标签之间放置空格或任何其他分隔符,因此请勿这样做。
所以,只需将标签一个接一个地放置即可, 像这样:
sudo-user ALL=(ALL) NOEXEC:NOPASSWD: ALL
答案2
您不需要为此添加标签,因为noexec
默认输入行也需要一个布尔标志:
noexec
如果设置,则通过 sudo 运行的所有命令都将表现为已设置 NOEXEC 标记,除非被 EXEC 标记覆盖。请参阅下面的 NOEXEC 和 EXEC 的描述以及防止外壳逃逸本手册末尾部分。这个标志是离开默认情况下。
所以你需要的是
Defaults noexec
这将出现与 telcoM 在 中指出的相同问题他们的答案
。它将阻止visudo
运行(因为这需要启动单独的编辑器进程),因此之后撤消更改将变得更加困难。
答案3
结合目前给出的两个答案,这个怎么样:
Defaults noexec
root ALL=(ALL) ALL
%wheel ALL=(ALL) ALL
sudo-user ALL=(ALL) EXEC:NOPASSWD: ALL
fred ALL=(ALL) NOPASSWD: user_allowed_commands
其实我是建议给予 sudo 用户不受限制的访问权限。这似乎是推荐的方法(至少在 Ubuntu 等中),而不是使用 root。我已经在审核 /etc/sudoers 目录了。这允许 fred 运行“user_allowed_commands”中的命令列表(假设不需要 fork/exec,这似乎不太可能,TBH - 或者我误读了 noexec 正在做什么?)
我想从 @telcoM 添加此内容: 用户可以随意解除的限制并不是真正的限制。
在我看到的所有 SELinux 实现中,它都不是一成不变的,因此任何用户都可以运行 setenforce permissive,并且所有限制都将被删除。