ToutSurTout.biz
Chrooter Apache httpd, bonne ou mauvaise idée ?


Sur mon serveur perso, je chroote Apache httpd depuis 2 ans et demi pour essayer mais ça cause tout un tas de problèmes pour un gain en sécurité pas évident du tout... Tant qu'à faire, voici quelques problèmes dont je me souviens et que je n'ai pas encore documenté :
   * Il fallait quand même créer les dossiers correspondants au DocumentRoot de chaque virtualhosts dans /var/www (ou autre chemin si vous l'avez changé...) sinon erreur au démarrage. Ça ne semble plus être nécessaire de nos jours.

   * Il faut charger explicitement les librairies utilisables. Genre si l'on a besoin d'une résolution de noms, il faut copier /etc/resolv.conf dans le chroot (au même emplacement, ofc) et ajouter ceci à la conf' Apache : « LoadFile /lib/x86_64-linux-gnu/libnss_dns.so.2 » sinon plus de résolution des noms et ces messages dans les logs :
   « PHP Warning:  file_get_contents(): php_network_getaddresses: getaddrinfo failed: Name or service not known in /var/www/[...] on line 3
     PHP Warning:  file_get_contents([...]): failed to open stream: php_network_getaddresses: getaddrinfo failed: Name or service not known in /var/www/[...] on line 3 »

   * Il faut copier /usr/share/zoneinfo et son contenu dans le chroot sinon PHP se vautrera dès qu'une fonction relative au temps/date sera utilisée. Exemples : « PHP Fatal error:  date_default_timezone_get(): Timezone database is corrupt - this should *never* happen! », «  PHP Fatal error:  strtotime(): Timezone database is corrupt - this should *never* happen! », « PHP Warning:  strtotime(): Invalid date.timezone value 'Europe/Paris', we selected the timezone 'UTC' for now. », « PHP Warning:  date_default_timezone_get(): Invalid date.timezone value 'Europe/Paris', we selected the timezone 'UTC' for now. ».

   * Problème de suppression des fichiers de session (stockés dans session.save_path). PHP n'a pas de mécanisme pour supprimer automagiquement ces fichiers. Sous Debian GNU/Linux, c'est stocké dans /tmp qui est souvent un tmpfs qui se vide donc à chaque extinction du serveur. De plus, un script, /usr/lib/php5/sessionclean est exécuté en cron toutes les 30 minutes. Problème : ce script récupère bien le chemin où sont stockés les fichiers... mais sans tenir compte du chroot. Ainsi « session.save_path = /tmp » dans le php.ini d'un PHP exécuté dans un chroot Apache httpd ne désigne pas /tmp mais $chrootdir/tmp (/var/apache/chroot/tmp dans mon cas puis chrootdir = /var/apache/chroot). Mon workaround :
       * Dupliquer /usr/lib/php5/sessionclean en /usr/local/lib/php5-sessionclean ;

       * Définir moi-même $save_path en commentant save_path=$(echo [...]) et en le remplaçant par « save_path=/var/apache/chroot/tmp »

       * Dupliquer /etc/cron.d/php5 en /etc/cron.d/php5-custom dans lequel j'appelle /usr/local/lib/php5-sessionclean au lieu de /usr/lib/php5/sessionclean

       * systemctl restart cron pour prendre en compte cette modification

   * Problème avec la validation des certificats x509.

   * Les sockets UNIX deviennent compliquées à utiliser pour communiquer avec les SGBD. On doit donc utiliser des sockets TCP... C'est déjà le cas par défaut donc ça n'entraîne pas de contraintes supplémentaires.