我们都见过“fork 炸弹”,即使在非特权 shell 中执行,它也会使主机无响应:
警告:不要执行以下 shell 脚本。只是不要。
:(){ :|:& };:
我也知道cgroups,Linux内核级进程分组结构,可以分配“控制器”来限制内存、CPU消耗、I/O调度优先级等。
理论上,应该可以使用这种控制机制来允许用户在自己的 shell 中执行 fork 炸弹,而不会使主机系统陷入瘫痪。
因为我不太清楚如何fork 炸弹会消耗资源,我不知道如何使用 cgroup 来做到这一点。
答案1
就我而言,我认为cgroups
这里有点过分了。然而,ulimit
每当我运行一些带有系统调用的东西时,我倾向于使用它fork
(糟糕的经历使它成为一种习惯......):
$ ulimit -u 2500
$ ./mypotentiallydeadlyprogram
这样,我对当前 shell 设置了 2500 个进程限制。因此,fork
如果调用次数太多,我的调用最终会失败,从而防止系统崩溃,并允许我猛烈地点击Ctrl+ C。
在我的机器上,我发现 2500 是一个很好的限制,但您可能需要根据您的机器可以承受的范围以及您希望叉子炸弹走多远来增加/减少该值。还要记住,你的机器需要产生东西才能生存,不要让它窒息。 我见过有人在他们的 中写下这个~/.bashrc
,因此甚至限制了他们会话的主要 bash。虽然这对系统管理员来说非常有趣,但用户对于登录后冻结感到非常不高兴。
虽然ulimit
可用于设置临时限制,但如果您具有 root 访问权限(并且希望对特定用户强制实施限制),则可以设置更永久的限制。这可以通过以下方式完成/etc/security/limits.conf
:
# <domain> <type> <item> <value>
youruser soft nproc 2500
youruser hard nproc 2750
在上述设置中,youruser
软限制为 2500 个进程(最多 2750 个)。该文件允许您为系统上的各种实体(用户、组……)设置各种限制。看一下如果您需要更多信息,请查看其文档。但请注意,这是系统范围的配置,这意味着不应用此限制每个外壳为了youruser
。
顺便说一句,/proc/sys/kernel/pid_max
将包含您的内核可以授予的最大 PID。由于 PID 是可重用的,您可能会认为这与您的最大进程数。