... or why PHP sucks so much? It is quite common (at least for me) finding abused web applications on shared hosts around. The most typical case is finding some kind of IRC bot running as www-data and a few unauthorized files around used for phishing, cross-site scripting or what else. That motivated me to try playing with
mod_chroot in order to minimize the possibility of webapps abuse from our friendly kiddies^Wcrackers.
Mod_chroot is a nice tiny Apache module whose purpose is the confinment of webapps within a limited tree, where nothing but a few files and dirs are available to try exploits and abuse badly written code.
Unfortunately, I found that mod_chroot poses one major problem (among others, see its CAVEATS doc): the sucking mail() function is
not working out of the box, because PHP folks - God knows why - decided to implement that stuff by calling a local /usr/sbin/sendmail program within a shell call. The most sane option is simply ignoring the issue and living happy with a disabled local mail() function. A nice solution in that case is using a PEAR Mail module, which is able to send mails via SMTP in much more elegant way. Unfortunately, there are quite a good number of morons out there, and that could be not a viable option if you are the system administrator of a bounce of shared hosts which are exposed to those morons, who absolutely need a working mail() function.
After a few googling around, I did find that many people had the same problem, but none found (or explained) a working and neat solution for a working mail() implementation, so I'm writing some notes about that. My implementation is based on a nice tiny program (
mini_sendmail) which has the great advantage of not requiring a configuration file or a spool directory to work. It also works without suid bit on, which is a good thing as well. It is statically compiled by default, so it simplifies things a lot. In order to have mail() working you need also to install a (statically compiled) shell, e.g. bash-static as
sh under the /bin directory of your chroot tree (a more tiny shell would be appropriate). I commented out the silly username autodetection code in the mini_sendmail.c source, because it creates some problem within an empty chroot tree (it failed with a "can't determine username" message with or without the /etc/passwd file available).
Now, the next step is using an entry like
sendmail_path = /usr/sbin/sendmail -t -fwww-data@your.domain -s127.0.0.1 in your
php.ini file. You can also use another IP address if your SMTP server is not your localhost or you used some more exotic routing setup. Having a suitable
/etc/hosts is also useful. A final trick is adding a
var/lib/php4 or what ever directory is required to store PHP session files. No other files should be required in order to have all working. Of course, you have also to use inet sockets for any required connection (e.g. mysql) but this is typically the default in etch. I would also suggest to add only ad hoc statically-compiled binaries within the chroot tree when required, else you will need to store all required shared libs: in that case you will need to find binaries requirement by using ldd and chroot to find loading/running errors by means of an usual trial-and-error cycle.