What do you recommend for setting up a shared server with php from a security/performance point of view?

Apache mod_php (how do you secure that? other than safe_mode as it won't be in PHP6)

Apache CGI + suexec

Lighttpd and spawn a FastCGI per user

LE: I'm not interested in using an already made control panel as i'm trying to write my own so i want to know what's the best way to setup this myself.
I was thinking in using Lighttpd and spawn a fastcgi for every hosted user making the fcgi process run under his credentials (there is a tutorial for this on lighttpd wiki).
This would be somewhat secure but would this affect performance (lots of users / memory needed for every fcgi) so much that it's not a viable solution?

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
If this question can be reworded to fit the rules in the help center, please edit the question.

4 Answers
4

Personally, while Lighttpd is OK, I would go with Nginx + FastCGI if you end up going with a lightweight webserver + FastCGI solution. I've run benchmarks and read all the code, and Nginx is an order of magnitude faster/more stable under load -- it's very good.

But, that's not what you asked. Essentially, I would say there's a spectrum of security/scaleability vs. speed tradeoffs in the three options you list, and you just need to decide where you want to be. If you're a shared hosting provider with untrusted users installing god-knows-what PHP apps you'll lean more toward security, if this is shared amongst more trusted users you might lean toward performance. Here are my thoughts:

CGI + suexec: This is by far the most secure, and most efficient/scaleable for you in terms of numbers of users/sites in a shared hosting environment. Processes are spawned and memory used only as requests come in. Of course, the CGI-spawning makes this the slowest for execution time of individual scripts. How much slower? Well you would have to benchmark, but generally if people are running long-running apps (i.e. something like WordPress which takes 0.25-0.5 seconds just to load its libs and initialize on each request), then the CGI-spawning penalty starts to look pretty negligible in context.

FastCGI: The issue here (and it doesn't matter if your webserver is Apache, Lighttpd or Nginx) is figuring out how many FCGI child processes you let each user leave running, because each process eats memory equal to the size of the PHP interpreter (in Linux not all of it is wired of course, but I digress). And, unlike mod_php, these processes aren't shared among users so you have to limit per user. For instance, Dreamhost caps this at 3 for their customers -- now, for a customer running a website that gets bursts of more than 2-5 page views a second, that's actually pretty bad because those requests just stack up and the site hangs. Now, I like FastCGI with a lightweight webserver when I'm running apps on a dedicated server/cluster, when I can give the app hundreds of FCGI children (all with webserver privs of course, à la Apache/prefork + mod_php). But, I don't think it makes sense for shared hosting where you have to allocate/cap the FCGI children per user.

Apache + mod_php: Least secure since everything running with webserver privs, but your pool of live PHP processes is shared so it's best on the performance end. From a developer perspective, I can't tolerate php_safe mode, and from a sysadmin perspective it's really only an illusion of security (it mitigates against stupid users but doesn't protect from an actual attack) so I would actually rather have CGI if my other option has to include safe_mode.

Dreamhost does sort of a hybrid, they do Apache CGI + suexec by default, but let the (small) percentage of their more users who are sophisticated elect to do FCGI if they want to, subject to a cap and their own monitoring of memory usage. That saves a ton of memory resources versus enabling FCGI for everyone by default.

Another issue if you're talking about standard commercial shared hosting is, Apache is full-featured, has modules for just about anything (including stuff like mod_security you might want), and your users will like it because all their .htaccess configs will work etc. -- you will run into support headaches with anything else when they go to install Drupal or WordPress or whatever (a lot less of an issue if we're talking internal users).

Personally I would recommend just keeping it simple to start and going with CGI + suexec for best security and scaleability. If your users want FCGI or mod_php and you have a good channel open for suggestions/communication with them, they'll ask for it, but either of these are a much bigger headache for you with only marginal performance improvements for them, so my suggestion would be to not do either of them initially but be responsive if they clamor for it.

I do sympathize with the desire to do something "interesting" like Lighttpd + FCGI instead of the standard Apache + CGI + suexec, but I deep down I really can't recommend it.

If you're running multiple servers, you could end up putting CGI on some and something else for the power users on the others. And be sure to have cron grep all the www dirs for things like old-ass versions of phpBB!

The challenge with securing a shared
hosting server is how to secure the
website from attack both from the
outside and from the inside. PHP has
built-in features to help, but
ultimately it’s the wrong place to
address the problem.

I’ve already written about a number of
solutions that work, but one option
I’ve been asked time and time again to
look at is using PHP + FastCGI. The
belief is that using FastCGI will
overcome the performance issues of
Apache’s suexec or mod_suphp, because
FastCGI processes persist between page
views.

But before we can look at performance,
the first question is: how exactly do
we get PHP and FastCGI running as
different users on the one web server
in the first place?