J'utilise tt-rss (
https://tt-rss.org/gitlab/fox/tt-rss/wikis/home) comme agrégateur de flux RSS et rssbridge (
https://github.com/sebsauvage/rss-bridge) pour produire des flux RSS pour des sites web qui n'en fournissent plus par pur choix. Depuis la mise à jour à Jessie, certains flux RSS passant par rssbridge ne sont plus fonctionnels : rssbridge présente une page vide (dans la version récupérable fin décembre 2015 sur github, on aura un message « Requested username can't be found. ». Les flux qui ne sont plus fonctionnels correspondent à des sites auxquels le bridge accède en HTTPS ou les sites web qui redirigent automatiquement sur leur version HTTP (on ne parle pas d'HSTS (voir
http://www.bortzmeyer.org/6797.html ) mais juste d'une bête redirection HTTP 301) comme Twitter, par exemple.
Si l'on n'a pas accès aux logs, on passe rssbridge en mode debug en commentant « error_reporting(0); » et en décommentant « ini_set('display_errors','1'); error_reporting(E_ALL); // For debugging only. » au début du fichier index.php de rssbridge. On se rend à l'URL défectueuse (ou dans les logs) et on obtient l'erreur complète :
« Warning: file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in /var/www/rssbridge/lib/Bridge.php on line 369
Warning: file_get_contents(): Failed to enable crypto in /var/www/rssbridge/lib/Bridge.php on line 369
Warning: file_get_contents(
http://twitter.com/aeris22): failed to open stream: operation failed in /var/www/rssbridge/lib/Bridge.php on line 369
Requested username can't be found. »
OpenSSL n'arrive donc pas à valider le certificat du serveur. NE PAS désactiver la vérification des certificats x509 de file_get_contents() avec une méthode comme celle exposée à l'adresse
https://stackoverflow.com/questions/26148701/file-get-contents-ssl-operation-failed-with-code-1-and-more (verify_peer -> false) : c'est une connerie, ça fonctionnait avant, on va réparer ça, c'est tout, pas la peine de créer une absence de sécurité. D'autant plus que ça nécessite de modifier le code de rssbridge, ce qui ne résistera pas aux mises à jour.
Si l'on écrit un bête fichier de test, comme « <?php echo file_get_contents('
https://twitter.com/') ?> » et qu'on l'exécute avec php-cli (php test-x509.php , par exemple), on se rend compte que cela fonctionne. Le même fichier de test accédé via un serveur web comme Apache httpd retourne l'erreur vue ci-dessus. On en déduit que cela vient soit de l'environnement d'exécution, soit d'un changement entre la conf' php-cli et la conf php Apache httpd.
Pourtant, les contextes TLS (obtenus avec « var_dump(openssl_get_cert_locations()); » sont identiques dans les deux cas :
« array(8) {
["default_cert_file"]=>
string(21) "/usr/lib/ssl/cert.pem"
["default_cert_file_env"]=>
string(13) "SSL_CERT_FILE"
["default_cert_dir"]=>
string(18) "/usr/lib/ssl/certs"
["default_cert_dir_env"]=>
string(12) "SSL_CERT_DIR"
["default_private_dir"]=>
string(20) "/usr/lib/ssl/private"
["default_default_cert_area"]=>
string(12) "/usr/lib/ssl"
["ini_cafile"]=>
string(0) ""
["ini_capath"]=>
string(0) ""
} »
/usr/lib/ssl/cert.pem n'existe pas sous Debian GNU/Linux mais /usr/lib/ssl/certs est un lien symbolique vers /etc/ssl/certs qui, grâce au package ca-certificate, contient bien les certificats d'AC x509 dont l'un d'eux a signé le certificat de Twitter...
Haaaaaaaaa mais j'y suis : cet Apache httpd tourne dans un chroot, « ChrootDir /var/apache/chroot » dans la conf' ! Or, /var/apache/chroot/usr/lib/ssl/certs n'existe pas !
De là, on a plusieurs solutions :
* Copier /etc/ssl/certs et tout son contenu dans /var/apache/chroot/etc/ssl/certs et faire un lien symbolique de /var/apache/chroot/usr/lib/ssl/certs vers /var/apache/chroot/etc/ssl/certs.
* Récupérer tout un magasin de certificats d'AC x509 et demander à PHP de l'utiliser
Dans les deux cas, la mise à jour des certificats reste problématique... Dans le deuxième cas, on peut lancer un wget en cron pour s'assurer d'avoir les derniers certificats et de ne plus avoir les certificats révoqués. Ces mises à jour sont plutôt rares (et dépendent de la source de votre magasin de certificats genre Microsoft, Mozilla, Google, Debian,...) mais mieux vaut être prévenu.
J'ai choisi la deuxième méthode. Pour la mettre en pratique, on :
* wget
https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt (magasin de certificats de Mozilla compacté par les dev de cURL, voir
http://curl.haxx.se/docs/caextract.html).
* En fonction des besoins, on peut aussi ajouter d'autres AC au bundle genre CACert (qui n'est plus dans le magasin de certificats de Mozilla). Il suffit de concaténer les certificats intermédiaires / root de l'AC au reste du bundle : cat ca-bundle.crt root.crt > ca-bundle.crt
* mkdir /var/apache/chroot/etc/ssl
* mv ca-bundle.crt /var/apache/chroot/etc/ssl/
* ajoute « openssl.cafile = /etc/ssl/ca-bundle.crt » dans /etc/php5/apache2/php.ini
* systemctl restart apache2
Maintenant, notre contexte TLS est le suivant :
« array(8) {
["default_cert_file"]=>
string(21) "/usr/lib/ssl/cert.pem"
["default_cert_file_env"]=>
string(13) "SSL_CERT_FILE"
["default_cert_dir"]=>
string(18) "/usr/lib/ssl/certs"
["default_cert_dir_env"]=>
string(12) "SSL_CERT_DIR"
["default_private_dir"]=>
string(20) "/usr/lib/ssl/private"
["default_default_cert_area"]=>
string(12) "/usr/lib/ssl"
["ini_cafile"]=>
string(19) "/etc/ssl/ca-bundle.crt"
["ini_capath"]=> string(0) "" } »
Notons le « ["ini_cafile"]=> string(19) "/etc/ssl/ca-bundle.crt" » ;)
rssbridge devrait parfaitement fonctionner (et si ce n'est pas le cas, il faut vider le cache avec rm -r <document_root>/cache/* ). \o/ On n'oublie pas de virer le mode debug de rssbridge. ;)
Pourquoi ça s'est mis à déconner avec le passage à Jessie ? J'avais dû déjà mettre en place un trick que je n'ai pas documenté ici, que j'ai donc dû oublier et j'ai dû accepter le remplacement de php.init durant la mise à jour, quelque chose dans ce goût-là.
Le mieux étant de ne pas chrooter Apache httpd : ça cause tout un tas de problèmes pour un gain en sécurité pas évident du tout (voir
http://shaarli.guiguishow.info/?08T1Cw).