Sudo:默认不允许 shell 转义

Gra*_*lls 3 linux sudo

我无法弄清楚如何为任何命令禁用 shell 转义,以便我可以(这是一个示例!)执行以下操作:

sudo-user ALL=(ALL) NOEXEC: NOPASSWD: ALL
Run Code Online (Sandbox Code Playgroud)

sudoers 手册是这样说的:

一个命令可能有零个或多个与之关联的标签。有八种可能的标签值,NOPASSWD、PASSWD、NOEXEC、EXEC、SETENV、NOSETENV、LOG_INPUT、NOLOG_INPUT、LOG_OUTPUT 和 NOLOG_OUTPUT。一旦在 Cmnd 上设置了标签,Cmnd_Spec_List 中的后续 Cmnds 将继承该标签,除非它被相反的标签覆盖(即:PASSWD 覆盖 NOPASSWD 和 NOEXEC 覆盖 EXEC)

但这并没有描述如何设置多个标志。使用逗号似乎不起作用(它将第二个标签视为别名)

更好的是,我想设置一个默认值,所以上面的行是:

defaults NOEXEC     
sudo-user ALL=(ALL) NOPASSWD: ALL
Run Code Online (Sandbox Code Playgroud)

我知道 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
Run Code Online (Sandbox Code Playgroud)

tel*_*coM 17

不要这样做。

您可以sudo-user以任何用户身份运行任何命令。这包括 /etc/sudoers使用不需要执行子流程的任何工具进行修改的能力。您可能认为 excludes visudo,但严格来说,您不需要 visudo编辑/etc/sudoers.

比如,例如:

sudo-user$ sudo sed --in-place -e '/^sudo-user/s/NOEXEC://' /etc/sudoers
Run Code Online (Sandbox Code Playgroud)

...用户刚刚取消了NOEXEC:限制。

用户可以随意删除的限制不是真正的限制。


此外,NOEXEC:可能会导致问题。它不只是防止shell转义:它阻止执行的程序sudo,从直接启动任何其他程序。这可能会产生很多后果。

例如,如果您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:')
Run Code Online (Sandbox Code Playgroud)

这是有关如何为文件构建用户规范行的详细说明。阅读可能有点乏味,但它确实包含您需要的信息。sudoers

让我们使用您的示例行来解决这个问题:

sudo-user ALL=(ALL) NOEXEC: NOPASSWD: ALL
Run Code Online (Sandbox Code Playgroud)

整行被称为用户规范,或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)
  • optional SELinux_Spec,在您的示例中不存在
  • 零个或多个Tag_Specs,这是您想了解的部分
  • Cmnd,命令,这就是ALL你的情况。

singleTag_Spec只是列出的关键字之一,末尾带有冒号,没有明确列出逗号、空格或其他分隔符。该Cmnd_Spec ::=行告诉我们在该行上放置空格的确切位置。由于没有在标签之间放置空格或任何其他分隔符的说明,所以不要这样做。

所以,只需一个接一个地放置标签,就像这样:

sudo-user ALL=(ALL) NOEXEC:NOPASSWD: ALL
Run Code Online (Sandbox Code Playgroud)

  • 我倾向于同意他的观点:如果你允许所有命令,那么防止 shell 逃逸是你最不担心的。虽然我想说当您需要授予某些用户权限以使用某些需要高权限且恰好包含 shell 转义功能的特定工具时,`noexec` 可能有其一席之地。如果您打算像您一样使用 sudo描述以满足记录所有特权命令的要求,请参阅 [此服务器故障帖子中的审计建议。](https://serverfault.com/q/470755/442837) (2认同)
  • 如果您想为用户提供某种形式的有限 root 访问权限以运行某个程序,作为系统管理员,您有责任仔细检查程序的功能并确保它不包含任何 shell 转义。如果它包含一个 shell 转义,那么 - 经过仔细测试 - 您可以*也许*使用 NOEXEC 允许它。只是在所有事情上都使用 NOEXEC 是一种错误且危险的懒惰方式。 (2认同)

Jig*_*aga 5

您不需要为此添加标签,noexec默认输入行的布尔标志也是如此:

noexec

如果设置,则通过 sudo 运行的所有命令都将表现为已设置 NOEXEC 标签,除非被 EXEC 标签覆盖。请参阅下面对 NOEXEC 和 EXEC 的说明以及本手册末尾的防止 shell 转义部分。默认情况下此标志是关闭的。

所以你只需要

Defaults        noexec
Run Code Online (Sandbox Code Playgroud)

这将与 telcoM 在他们的回答中指出的问题相同 。它将阻止visudo运行(因为这需要启动一个单独的编辑器进程),因此之后撤消更改将更加困难。