The Daily Shaarli
Soit une installation nginx + php-fpm + mysql tout à fait standard avec un CMS (WordPress mais ce qui suit est applicable à tout script PHP) fraîchement installé (aucun plugin, aucun thème mais peut-être du contenu) mais pas par nous. Pas de modules PHP "chelous" installés (ls -lh /etc/php5/mods-available) comme memcached. Quand on accède au site web, nginx nous répond « 502 Bad Gateway Error ».
Dans le log de nginx, on a :
recv() failed (104: Connection reset by peer) while reading response header from upstream
Dans le log php-fpm (/var/log/php5-fpm.log par défaut sous Debian), on a :
[...] child [...] exited on signal 11 (SIGSEGV) after [...]
À chaque fois que l'on accède au WordPress, vlam, segfault. Si l'on n'y accède pas : il ne se passe rien. Ce n'est pas le paramètre « pm.max_children » qui est atteint.
On a assez de RAM (1,5G libre :D ). La valeur de memory_limit, 128M, est amplement suffisante pour un WordPress (même mon WP avec des posts longs d'une centaine de pages A4 se contente de 64M :D).
Sur un moteur de recherche, on trouve que cela peut être un problème d'accès en écriture au dossier dans lequel sont créés les fichiers relatifs aux sessions, session.save_path (/var/lib/php5/sessions par défaut sous Debian). Il n'en est rien pour moi.
De même, on trouve que cela peut être relatif à opcache dans des cas très particuliers. Exemple : https://serverfault.com/questions/629231/how-can-a-bog-standard-wordpress-install-break-php . Même en désactivant opcache (mv /etc/php5/mods-available/opcache.conf /root/ ; systemctl restart php5-fpm), ça ne fonctionne pas.
On tente d'exécuter l'index du WP avec php-cli genre sudo php /chemin/vers/WP/index.php. sudo pour éviter les problèmes de permissions pour les « require() ». « Erreur de segmentation ». Même erreur, donc.
Bon, on se résout à sortir strace : sudo strace php /chemin/vers/WP/index.php. On voit PHP communiquer avec MySQL pour récupérer les articles, les commentaires, etc. puis une 20aine d'appels systèmes « brk() » puis SIGSEGV. brk() permet d'allouer de la RAM. Pourtant, on a déjà vu que l'on a bien assez de RAM. Ha, pour que strace ne tronque pas les paramètres des appels systèmes : strace -s 9999.
On se résout à demander la création d'un core dump et à l'analyser. Voir cet excellent tuto : https://ma.ttias.be/generate-php-core-dumps-segfaults-php-fpm/ . Sous Debian, il faut aussi installer les symboles de debug qui sont packagés séparément (car ça consomme de l'espace disque sans pour autant être utile au plus grand nombre de personnes) : apt-get install php5-dbg.
On constate que notre bt a plus de 30 000 appels de fonctions et que c'est toujours les 3 mêmes :
#30829 0x002219c0 in execute_ex (execute_data=execute_data@entry=0xb87988) at /build/php5-3mKzyG/php5-5.6.27+dfsg/Zend/zend_vm_execute.h:363
#30830 0x001ee2f6 in dtrace_execute_ex (execute_data=0xb87988) at /build/php5-3mKzyG/php5-5.6.27+dfsg/Zend/zend_dtrace.c:73
#30831 0x0026d460 in zend_do_fcall_common_helper_SPEC (execute_data=) at /build/php5-3mKzyG/php5-5.6.27+dfsg/Zend/zend_vm_execute.h:592
Conclusion : il y a une boucle infinie dans un des fichiers .php et l'erreur de segmentation vient du fait que PHP explose sa pile.
Pour savoir dans quel fichier et quelle ligne, soit on installe xdebug (mes notes sont ici http://shaarli.guiguishow.info/?7b7cDA ) soit on tente sa chance en cherchant les derniers fichiers modifiés genre find -type f -mtime -2. Sur un CMS où la craderie peut avoir été faite n'importe où, la deuxième méthode est intenable sauf sur un coup de chance (et quand xdebug vous rebute, vous croyez subitement à la notion de chance :D).
Au final, on se souvient qu'il n'y a pas de limite de récursion par défaut en PHP. Cette limite existe uniquement si l'on a installé xdebug.
Si PHP-FPM est configuré pour écouter sur une socket TCP et que, dans les logs nginx vous avez l'erreur « upstream timeout (110: Connection timeout) while connecting to upstream » et que PHP-FPM est bien en cours d'exécution et qu'il a bien ouvert son port, et que la valeur de listen.allowed_clients est OK dans /etc/php5/fpm/pool.d/www.conf , essayez de faire un telnet sur le port de PHP-FPM genre telnet 127.0.0.1 5900. Si ça ne fonctionne pas, vérifiez les règles de filtrage de votre pare-feu. ;)
Petits rappels sur les listes de contrôle d'accès au système de fichiers POSIX.
Un service gratos et sans enregistrement préalable pour recevoir des SMS sur des numéros jetables consultables par tous-toutes. Le yopmail du SMS, en somme. Pas prise de tête, ça juste fonctionne.
C'est super pratique quand un GAFAM demande impérativement un numéro de téléphone pour recevoir un foutu code de sécurité, par exemple.
Évidemment, il ne faut pas utiliser ce service pour recevoir des infos sérieuses ou des infos récurrentes (la pérennité des numéros n'est clairement pas assurée). Donc, ne pas utiliser ce service pour de l'authentification à deux facteurs ou sur un site web qui conservera votre numéro pour un usage légitime futur, par exemples. Mais c'est super utile pour des comptes fake sur un certain nombre de sites web gourmands en données personnelles.
