1

I got this script named fork.sh:

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

If I call it through suexec my whole system will consume 99% cpu. To prevent a normal bash forkbomb I used the limits.conf and set nproc to 50. This works as expected.

But if I call the above mentioned script through suexec over httpd, I see in top over 6000 tasks and a sys cpu use >97%. I can see multiple entries of user3 fork.sh with ~ 0,6% cpu. If I call systemd-cgtop the system.slice have 100% cpu and system.slice/httpd.service 75%

I restricted httpd with cgroups:

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

I don't get it, why ulimits and cgroups will not handle this issue.

4
  • Are you running it via http through suexec so that it runs as root? Or are you going via root through suexec to run as http? If it's the former: the problem is /etc/limit.d/90-nproc.conf probably exists and does so for a good reason. If you restrict the number of processes runnable as root, you can essentially shut yourself out of the system.
    – Otheus
    Jun 2, 2015 at 8:46
  • no i don't restrict root. suexec runs for user3 and i defined a group sshusers and restricted this group in /etc/limit.d/20-nproc.conf like this: @sshusers nproc 50. user3 has a vhost config i call with lynx user3.com/cgi-bin/fork.sh. i think httpd get to much requests or something like this.
    – bubele
    Jun 2, 2015 at 8:58
  • I forgot something very important. See answer
    – Otheus
    Jun 2, 2015 at 9:18
  • i can't see your answer? For information my setup is the following: multiple vhosts with seperated system users for php-fpm and suexec. each vhost have a seperated homedir which is used as documentroot.
    – bubele
    Jun 2, 2015 at 9:37

1 Answer 1

0

The limits files are utilized by PAM. The stock suexec provided by apache still does not recognize or utilize PAM. Patches exist. And you can modify the source directly to invoke setrlimit (it looks pretty easy - see the setlimit(2) man page.) But as is, suexec will not recognize anything you do with limits.

You can still set ulimits from within apache, but I think this is undesirable, especially in the pre-fork model, because then you limit the load your http server can handle. Further, I'm not sure if limits will carry over to the suexec environment because I'm not sure how suexec does its job.

The reason CPUShares won't help you here is because your fork bomb is a resource hog, but the resources aren't really in the userland CPU cycles. By the time CPU accounting becomes involved, it's too late: your system has no free memory or process slots to try to run the program.

You might try prlimit, part of util-linux so it should be standard with your installation. If you do this:

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

bash: fork: retry: No child processes

So the little 2-fork process failed.

Unfortunately, I don't see a sound way you can get prlimit involved in the execution chain. Apache has screwed themselves and all of us by providing a deprecated suexec module that isn't flexible enough to meet the basic demand, and is straight-jacketed enough that any real solution requires blasting a hole through security.

5
  • ok then the best solution is to patch apache? iam on a centos system, there is no setrlimit installed. is there no way to restrict it with systemd and cgroups? To ulimit the apache user is no alternative, i know.
    – bubele
    Jun 2, 2015 at 9:48
  • setrlimit is a system call. We're talking about patching at source level and compiling. For suexec itself, that's pretty trivial, since it's a small program. However, it's packaged with apache web server's sources. All things considered, it's better to try to apply the PAM patch for suexec. With systemd you get all that is documented in systemd.resource-control which isn't much. The more I look at systemd the less I like it: bloatware doesn't suit Linux. At least it's not upstart. Maybe prlimit is the way to do this. Revising answer.
    – Otheus
    Jun 2, 2015 at 10:19
  • Can I assume you're trying to make a web-server environment for a multi-user group and granting users the ability to run CGI within their own context? And further, trying to have some sane guarantee that said users wont run your system out of resources?
    – Otheus
    Jun 2, 2015 at 10:37
  • ok thx. yes your right with your assume.
    – bubele
    Jun 2, 2015 at 10:48
  • In that case, the better answer might be: run an HTTP instance for each user, and toss out the use of suexec altogether. As long as your users are under 20 or so, this solution has some nice properties: You as the sysadmin can use systemd as above to control the CPU shares of each user's HTTP process-tree. The users will have the ability to have near complete control over the HTTP environment -- with some restrictions. The way to do this would be to set up a reverse proxy/load-balancer that handles all inbound requests and directs them to each user's HTTP running on its own port.
    – Otheus
    Jun 2, 2015 at 13:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.