Apache and user-separated PHP FastCGI processes without using Suexec
Published on
For most of this evening I’ve been battling against a problem that’s haunted me for a while – how to get PHP scripts to run with sane permissions, rather than “apache/apache” for all the users on my web server. Pretty much every tutorial on the Internet advocates one of two approaches:
- Using Suexec (or some variant thereof)
- Using the ITK or peruser MPM
However, using suexec isn’t feasible for me – my virtual hosts are dotted all over the file system, not served from /var/www as Suexec demands, and I don’t want to start moving my customers files around in case they have hard coded file system paths, and I don’t want to roll my own Apache – I want to stick with the official Fedora RPMs. There’s a third method too – suPHP, which runs a script as the user which owns it, but this also seems a bad idea imo (just like PHP’s “Safe Mode”).
I’ve also been investigating the feasibility of moving to Lighttpd (but decided against it), and stumbled across a tutorial on how to accomplish this with Lighttpd and FastCGI and thought I could take the same tack with Apache. So, I implemented the first part of the tutorial (using spawn-fcgi to start up the PHP FastCGI clients), but it was configuring Apache to use it that flummoxed me. First off, you can not use external FastCGI servers with Apache’s built-in mod_fcgid, you have to use the mod_fastcgi module, so I compiled, configured and installed that. Then I played around with the Apache config to get it to do what I want to do, and the following in my www.pling.org.uk VirtualHost seems to accomplish the job:
FastCGIExternalServer /srv/pling.org.uk/fcgi-bin -socket /var/lib/fastcgi/chris.sock
ScriptAlias /fcgi-bin /srv/pling.org.uk/fcgi-bin
AddHandler php5-fastcgi .php
Action php5-fastcgi /fcgi-bin virtual
The first path in FastCGIExternalServer is a “virtual” path, and anything that gets mapped to there gets sent to the PHP FastCGI server. The ScriptAlias simply maps that virtual directory to be inside of the root (for some reason putting the virtual directory directly in my document root confused my .htaccess rules sending it into an infinite rewrite loop). The final 2 lines simply tell Apache to deal with .php files as “php5-fastcgi” and to map this “php5-fastcgi” type to our fcgi-bin script alias, so all .php files get sent to FastCGI.