Envoi de mail en PHP chrooté
Un de nos clients dispose d'un site (CMSMS, PHP) en environnement chrooté (CentOS), mais cela présente un petit inconvénient : l'envoi de mails ne se fait pas/plus.
Chroot
Voici ce que nous dit Wikipedia sur la commande chroot :
Cette commande permet d'isoler l'exécution d'un programme et d'éviter ainsi la compromission complète d'un système lors de l'exploitation d'une faille. Si un pirate utilise une faille présente sur l'application chrootée, il n'aura accès qu'à l'environnement isolé et non pas à l'ensemble du système d'exploitation. Cela permet donc de limiter les dégâts qu'il pourrait causer.
Le problème ?
La fonction mail() de PHP ne fonctionne pas car elle n'a pas accès à sendmail (ou MTA équivalent) puisqu'ils sont généralement installé en dehors du système chrooté.
La solution : mini_sendmail
mini_sendmail permet d'envoyer les messages reçus par son entrée standard (au sens C) vers le serveur SMTP local. Il peut donc être utilisé au sein d'un chroot, mais comme il utilise un pipe, il a besoin d'un shell chrooté.
Nous allons effectuer une installation prépatoire de mini_sendmail
# cd /opt
# wget http://www.acme.com/software/mini_sendmail/mini_sendmail-1.3.6.tar.gz
# tar -zxvf mini_sendmail-1.3.6.tar.gz
# cd mini_sendmail-1.3.6
# make
mais nous avons rencontré un problème
gcc -O -s -static mini_sendmail.o -o mini_sendmail
/usr/bin/ld: cannot find -lc
collect2: ld returned 1 exit status
make: *** [mini_sendmail] Error 1
Cela se "répare" facilement en installant la libc
# yum install glibc-static
La compilation peut être refaite.
Maintenant, nous copions l'exécutable généré, et le shell dans l'environnement chrooté (dans /srv)
cp mini_sendmail /srv/usr/sbin/sendmail
cp /bin/sh /srv/bin/
Nous utilisons également la commande l2chroot de nixCraft qu permet de recopier les librairies dont dépend l'exécutable. Il faut modifier ce script pour modifier la variable d'environnement BASE.
l2chroot /opt/mini_sendmail-1.3.6/mini_sendmail
l2chroot /bin/sh
Testons maintenant le bon fonctionnement de mini_sendmail
#chroot /srv /usr/sbin/sendmail
/usr/sbin/mini_sendmail: can't determine username
Ah ... finalement, mini_sendmail non plus ne fonctionne pas :)
En fait, il suffit de patcher le code source du mini_sendmail pour passer le problème. En ligne 148 du fichier mini_sendmail.c, on modifie :
username = getlogin();
par
username = "apache";
et voilà, après une recompilation, tout rentre dans l'ordre.
Webographie
Setup sendmail php mail() support for chrooted Lighttpd or Apache web server, nixCraft, 08/11/2006
Lessons learned from Apache mod_chroot vs. PHP’s mail(), Spoox?!, 04/01/2011
Linux: /usr/bin/ld: cannot find -lc Error and Solution, nixCraft, 15/05/2011