Systemcrash suexec forkbomb.sh ulimits

Systemcrash suexec forkbomb.sh ulimits

我得到了这个名为 fork.sh 的脚本:

#!/bin/sh
forkbomb() { forkbomb | forkbomb & } ; forkbomb

如果我通过 suexec 调用它,我的整个系统将消耗 99% 的 cpu。为了防止正常的 bash forkbomb,我使用了 limit.conf 并将 nproc 设置为 50。这按预期工作。

但是,如果我通过 httpd 上的 suexec 调用上述脚本,我会看到超过 6000 个任务,系统 cpu 使用率 >97%。我可以看到 user3 fork.sh 的多个条目,cpu 占用率约为 0.6%。如果我调用 systemd-cgtop,system.slice 的 cpu 利用率为 100%,system.slice/httpd.service 的 cpu 利用率为 75%

我用 cgroups 限制了 httpd:

 systemctl set-property --runtime httpd.service CPUShares=600 MemoryLimit=500M 

我不明白,为什么 ulimits 和 cgroups 不能处理这个问题。

答案1

这些limits文件由PAM. apache提供的库存suexec仍然无法识别或使用PAM补丁存在。您可以直接修改源代码来调用setrlimit(它看起来很简单 - 请参阅setlimit(2)手册页。)但按原样,suexec将无法识别您使用limits.

您仍然可以在 apache 中设置 ulimit,但我认为这是不可取的,特别是在 pre-fork 模型中,因为这样您就限制了 http 服务器可以处理的负载。此外,我不确定限制是否会延续到环境中,suexec因为我不确定suexec它是如何发挥作用的。

原因CPUShares在这里对你没有帮助,因为你的 fork 炸弹是一个资源霸主,但资源并不真正在用户态 CPU 周期中。当涉及 CPU 统计时,为时已晚:您的系统没有可用内存或进程插槽来尝试运行该程序。

您可以尝试prlimit其中的一部分,util-linux因此它应该符合您的安装标准。如果你这样做:

$ prlimit --nproc=1 bash -c bash -c id

bash: fork: retry: No child processes

所以这个小小的 2-fork 进程失败了。

不幸的是,我没有看到让 prlimit 参与执行链的合理方法。 Apache 已经把自己和我们所有人都搞砸了,因为它提供了一个已弃用的suexec模块,该模块不够灵活,无法满足基本需求,而且过于严格,任何真正的解决方案都需要在安全性上炸开一个洞。

相关内容