安全执行“分叉炸弹”

amp*_*ine 6 linux shell cgroups

我们都见过“分叉炸弹”,它会使主机无响应,即使在非特权 shell 中执行:

警告:不要执行以下 shell 脚本。只是不要。

:(){ :|:& };:
Run Code Online (Sandbox Code Playgroud)

我也知道cgroups,Linux 内核级进程分组结构,可以分配“控制器”来限制内存、CPU 消耗、I/O 调度优先级等。

从理论上讲,应该可以使用这种控制机制来允许用户在他们自己的 shell 中执行一个 fork 炸弹,而不会导致主机系统陷入困境。

由于我并不真正了解分叉炸弹如何消耗资源,因此我不确定如何使用 cgroups 来执行此操作。

Joh*_*ith 5

就我而言,我认为cgroups这里有点矫枉过正。但是,ulimit每当我在其中运行fork系统调用时,我倾向于使用它(糟糕的经历使它成为一种习惯......):

$ ulimit -u 2500
$ ./mypotentiallydeadlyprogram
Run Code Online (Sandbox Code Playgroud)

这样,我对当前的 shell 设置了 2500 个进程的限制。多亏了这一点,fork如果它们太多,我的调用最终会失败,从而防止系统崩溃,并让我疯狂地点击Ctrl+ C

在我的机器上,我发现 2500 是一个很好的限制,但是您可能希望根据您的机器可以承受的范围以及您希望叉形炸弹走多远来增加/减少此值。还要记住,你的机器需要产生东西才能生存,不要让它窒息。 我已经看到人们在他们~/.bashrc的 . 虽然这对系统管理员来说很有趣,但用户在登录后非常不高兴冻结。

虽然ulimit可用于设置临时限制,但如果您具有 root 访问权限(并希望对特定用户实施限制),则可以设置更永久的内容。这可以通过/etc/security/limits.conf

# <domain>      <type>      <item>      <value>
youruser        soft        nproc       2500
youruser        hard        nproc       2750
Run Code Online (Sandbox Code Playgroud)

在上述设置中,youruser软限制为 2500 个进程(最多 2750 个)。该文件允许您为系统上的各种实体(用户、组等)设置各种限制。如果您需要更多信息,请查看其文档。然而,注意,这是系统范围的配置,这意味着,该限制不被施加每壳youruser

顺便说一下,/proc/sys/kernel/pid_max将包含您的内核可以授予的最大 PID。由于 PID 是可重用的,您可能会认为这与您的最大进程数非常接近。