Ensemble réalisons
vos projets informatiques
Français Brezhoneg

Blog

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