这是基于这里的这个恶作剧问题。所描述的问题是有一个 bash 脚本,其中包含以下内容:
rm -rf {pattern1}/{pattern2}
rm -rf /
...如果两种模式都包含一个或多个空元素,则假设原始命令已正确转录并且 OP 正在执行大括号扩展而不是参数扩展,则该模式将扩展为 的至少一个实例。
在 OP对骗局的解释中,他指出:
命令 [...] 是无害的,但似乎几乎没有人注意到。
Ansible 工具可以防止这些错误,[...] 但是 [...] 似乎没有人知道这一点,否则他们会知道我所描述的不可能发生。
rm -rf /
因此,假设您有一个通过大括号扩展或参数扩展发出命令的 shell 脚本,使用Ansible是否会阻止该命令被执行,如果是,它是如何做到的?
rm -rf /
只要您使用 Ansible 来执行,以 root 权限执行真的“无害”吗?
我有虚拟机,让我们炸毁一堆!为了科学。
第一次尝试:
好的,所以
command
只是传递文字,没有任何反应。我们最喜欢的安全旁路
raw
怎么样?别再去了!删除所有文件有多难?
哦,但是如果它们是未定义的变量或其他东西怎么办?
好吧,那没有用。
但是,如果变量已定义但为空怎么办?
终于有进步了!但它仍然抱怨我没有使用
--no-preserve-root
.当然,它也警告我应该尝试使用
file
模块和state=absent
. 让我们看看这是否有效。好消息,大家!它开始试图删除我所有的文件!但不幸的是,它遇到了错误。我将解决这个问题并让剧本使用
file
模块作为练习来破坏所有内容给读者。不要运行任何你看到的超出这一点的剧本!你马上就会明白为什么。
最后,为了致命一击......
这个虚拟机是一只前鹦鹉!
有趣的是,上面没有做任何事情,
command
而不是raw
.file
它只是打印了关于使用with的相同警告state=absent
。我要说的是,如果你不使用它,似乎
raw
有一些保护可以防止rm
失控。但是,您不应该依赖于此。我快速浏览了 Ansible 的代码,虽然我发现了警告,但我没有发现任何实际上会抑制运行该rm
命令的内容。Ansible 会阻止
rm -rf /
在 shell 脚本中执行吗?我确实检查了 coreutils rm source,它具有以下内容:
从根目录擦除的唯一方法是越过此代码块。从这个来源:
我将此解释为该函数
get_root_dev_ino
返回 null on/
,因此 rm 失败。绕过第一个代码块(使用递归)的唯一方法是拥有
--no-preserve-root
并且它不使用环境变量来覆盖,因此它必须显式传递给 rm。我相信这证明除非 Ansible 明确传递
--no-preserve-root
给rm
,否则它不会这样做。结论
我不相信 Ansible 明确阻止
rm -rf /
,因为rm
它本身阻止了它。