Faire fonctionner CURL en HTTPS dans un environnement php-fpm chrooté

Cela faisait longtemps que je n’avais pas fait d’article sur ce blog. Ça me manquait un peu et comme je viens de passer 2h sur un problème avec php-fpm, curl et SSL, j’ai décidé d’en faire un article. En effet, je n’ai pas trouvé grand chose sur internet lors de mes recherches (y compris sur la référence stackoverflow !) donc je pense que cela peut aider d’autres personnes.

Je vais donner la solution (ou plutôt « ma » solution), tout en détaillant ce que j’ai fait pour trouver le problème, car ça permet d’aborder une commande que j’adore et qui me sauve régulièrement la mise : strace.

Une note avant de commencer. Toutes les commandes et configurations sont disponibles sur ce Gist également

Le contexte

Depuis quelques semaines je m’amuse avec PHP-FPM et notamment son option permettant de lancer PHP dans un environnement chrooté.

Initialement je m’étais dit que c’était une bonne idée du point de vue sécurité, mais en faisant quelques recherches, je me suis vite rendu compte que le chroot n’est pas une sécurité.
Pour preuve, c’est très simple de s’évader d’un chroot comme le montre cet article très instructif.

Bref, le soucis n’est pas là. La difficulté avec le chroot, est qu’il faut copier des bibliothèques systèmes et d’autres exécutables dans le répertoire « chrooté » afin que PHP puisse s’exécuter correctement. Il faut re-concevoir une sorte de « / » minimaliste, permettant de faire fonctionner juste ce que l’on souhaite.

Le problème, c’est qu’il y a toute la partie DNS et SSL à remettre en place dans cet environnement chrooté et ce n’est pas forcément évident, car il faut trouver les bons fichiers à copier par exemple puis faire la liste des dépendances manuellement.

Un premier exemple de gestion des dépendances

Pour illustrer cela, commençons par un exemple simple : chrooter l’exécutable de bash dans un répertoire « chroot_bash ». C’est simple car les dépendances de bash ne sont pas très nombreuses.

mkdir chroot_bash
mkdir -p chroot_bash/usr/bin
cp /usr/bin/bash chroot_bash/usr/bin
chroot chroot_bash/ bash
chroot: failed to run command ‘bash’: No such file or directory

Le fait de simplement copier l’exécutable de bash ne suffit pas, car bash à besoin de certaines bibliothèques qui ne sont pas installés dans l’environnement chrooté. Pour voir les bibliothèques qu’utilise bash, on peut utiliser la commande « ldd » :

ldd /usr/bin/bash
linux-vdso.so.1 =>  (0x00007fff22d80000)
libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007f15009d9000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f15007d5000)
libc.so.6 => /lib64/libc.so.6 (0x00007f1500413000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1500c0d000)

La plupart des bibliothèques sont dans /lib64, on va donc recréer ce dossier dans l’environnement chrooté puis copier les bibliothèques nécessaires à bash :

mkdir chroot_bash/lib64
cp /lib64/libtinfo.so.5 /lib64/libdl.so.2 /lib64/libc.so.6 /lib64/ld-linux-x86-64.so.2 chroot_bash/lib64/

Maintenant, si on teste à nouveau de lancer bash en chroot, on obtient un shell minimaliste :

chroot chroot_bash/ bash
bash-4.2# pwd
/
bash-4.2# ls
bash: ls: command not found

La commande « ls » n’est même pas installée, on peut l’installer en copier le binaire dans le dossier « bash_chroot » puis en utilisant « ldd » de la même manière pour installer les dépendances.

Voilà le genre de choses qu’il faut faire créer un environnement chrooté. Pour le moment, c’est assez simple car ldd donne tout ce qu’il faut. Cependant, dés que ça touche un peu au réseau, aux résolutions DNS et aux SSL, ça se complique.

Création d’un envionnement chrooté pour PHP

Abordons le vif du sujet, la préparation d’un environnement chrooté pour le bon fonctionnement d’une application PHP. On va se mettre pour objectif de faire fonctionner correctement WordPress dans un environnement chrooté avec php-fpm. Ca permet d’avoir un exemple concret.
On commence par créer un utilisateur, créer un dossier pour accueillir le site puis mettre la base de WordPress dedans pour commencer à travailler :

useradd -md /home/tuto tuto
mkdir /home/tuto/www
wget http://fr.wordpress.org/latest-fr_FR.zip
unzip latest-fr_FR.zip && mv wordpress/* /home/tuto/www
rm -rf wordpress/ latest-fr_FR.zip
chwon -R tuto: ~tuto

Ensuite, on génère un pool php-fpm (dans ma configuration, j’utilise un utilisateur par site et un pool par utilisateur) et la configuration nginx (minimaliste, largement améliorable).

cat /usr/local/etc/pool.d/tuto.conf
[tuto]
listen = /var/run/tuto.sock
listen.allowed_clients = 127.0.0.1
listen.owner = nginx
listen.group = nginx
user = tuto
group = tuto
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500
slowlog = /var/log/php-fpm/tuto-slow.log
chroot = /home/tuto
chdir = /www
env[HOSTNAME] = $HOSTNAME
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
php_flag[display_errors] = on
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session

La configuration PHP-FPM permettant le chroot est la ligne « chroot » surligné ci dessus. Les logs seront conservés dans l’environnement chrooté, tout comme les sessions PHP.

cat tuto.madrzejewski.com.conf
server {
    listen 80;
	server_name tuto.madrzejewski.com;
    root /home/tuto/www;
	access_log  /var/log/nginx/tuto.madrzejewski.com-access.log;
	error_log /var/log/nginx/tuto.madrzejewski.com-error.log;
	location = /favicon.ico {
		log_not_found off;
		access_log off;
	}
	location = /robots.txt {
		allow all;
		log_not_found off;
		access_log off;
	}
	# auth for admin directory
	location /wp-admin/ {
		auth_basic "Access restreint";
		auth_basic_user_file /etc/nginx/htpasswd/passwd;
	}
	# no PHP in upload directory
	location ~* /(?:uploads|files)/.*\.php$ {
    		deny all;
	}
	# hide sensitive files
	#location ~* \.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(\..*|Entries.*|Repository|Root|Tag|Template)$|\.php_
	#{
    #	return 444;
	#}
	# no cgi
	location ~* \.(pl|cgi|py|sh|lua)\$ {
        	return 444;
	}
	# no access to specific files
	location ~ /(\.|wp-config.php|readme.html|license.txt) {
    		deny all;
	}
	location / {
		# This is cool because no php is touched for static content.
		# include the "?$args" part so non-default permalinks doesn't break when using query string
		try_files $uri $uri/ /index.php?$args;
	}
	# no weird request
	if ($request_method !~ ^(GET|HEAD|POST)$ )
	{
		return 444;
	}
	location ~ [^/]\.php(/|$) {
		include /etc/nginx/fastcgi.conf;
		fastcgi_split_path_info ^(.+?\.php)(/.*)$;
		if (!-f $document_root$fastcgi_script_name) {
			return 404;
		}
		#fastcgi_pass 127.0.0.1:9000;
		# debug test chroot phpfpm
		fastcgi_param   SCRIPT_FILENAME /www/$fastcgi_script_name;
		fastcgi_pass unix:/var/run/tuto.sock;
		fastcgi_index index.php;
	}
	location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
		expires max;
		log_not_found off;
	}
}

Quelques détails sur la configuration :

  • J’utilise des sockets pour PHP-FPM, je trouve cela plus élégant que d’avoir différents ports d’écoute.
  • Dans nginx, la subtilité se trouve dans le fastcgi_param, le « SCRIPT_FILENAME » est modifié de telle sorte à ce que Nginx génère un chemin à partir /home/tuto et non à partir du « / » tout court (donc du point de vue de PHP, le / sera directement /home/tuto en réalité).

Maintenant, on peut commencer à peupler /home/tuto avec quelques fichiers nécessaires :

mkdir -p /home/tuto/{etc,usr/share,var/lib/php/session,var/log/php-fpm,tmp,lib64,lib,bin,dev}
cp -r /usr/share/zoneinfo /home/tuto/usr/share/
cp -r /etc/ld.so.cache /etc/resolv.conf /etc/ld.so.conf /etc/nsswitch.conf /etc/hosts /etc/localtime /home/tuto/etc/
mkdir -p /home/tuto/var/lib/mysql && touch /home/tuto/var/lib/mysql/mysql.sock
chown -R tuto: ~tuto
mount --bind /var/lib/mysql/mysql.sock /home/tuto/var/lib/mysql/mysql.sock
mknod /home/tuto/dev/null c 1 3 -m 666

A ce stade, nous avons un WordPress à peu près fonctionnel. Quelques notes supplémentaires :

  • Pour la base de données, la solution la plus élégante que j’ai trouvé était un « mount –bind » sur le socket de mysql sinon le chroot n’y a pas accès
  • La plupart des fichiers copiés sont pour les accès réseau, sans cela, le « localhost » du fichier de configuration de wordpress pour la base de données ne fonctionne pas par exemple (car contenu dans /etc/hosts)
  • Vous remarquez la dernière commande qui permet de créer un /dev/null dans l’envrionnement chrooté. Je pense que le /dev/null est trop utilisé pour être ignoré. Je n’ai pas testé sans, mais ça doit causer des problèmes « bizarres ».

Les choses qui ne fonctionnent pas

En apparence WordPress est fonctionnel, mais si vous allez dans la gestion des extensions et notamment l’ajout, vous aurez l’erreur suivante :

Erreur de wordpress sur la page d'ajout de plugin

Erreur de wordpress sur la page d’ajout de plugin

En activant le debug PHP et le debug de WordPress, on obtient :

Warning: Une erreur inattendue s’est produite. Quelque chose semble ne pas fonctionner avec WordPress.org ou la configuration de ce serveur. Si vous continuez à rencontrer des problèmes, veuillez essayer les forums de support. (WordPress n’a pas pu établir de connexion sécurisée vers WordPress.org. Veuillez contacter l’administrateur de votre serveur.) in /www/wp-admin/includes/plugin-install.php on line 83

Si on regarde le fichier PHP, on arrive sur le bloc de code suivant :

$request = wp_remote_post( $url, $http_args );
if ( $ssl && is_wp_error( $request ) ) {
	trigger_error( __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.' ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE );
	$request = wp_remote_post( $http_url, $http_args );
}$request = wp_remote_post( $url, $http_args );
if ( $ssl && is_wp_error( $request ) ) {
	trigger_error( __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.' ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE );
	$request = wp_remote_post( $http_url, $http_args );
}

Même problème avec Akismet si vous essayez d’activer votre clé d’api. Ces deux erreurs sont surtout présentes si votre blog est en SSL, car WordPress va faire des requêtes vers ces deux services (api wordpress.org et akismet) en SSL de préférence.

Je ne suis pas un expert WordPress, mais de ce que je vois, ça fait une requête, sans doute via CURL sur une API distante. En bidouillant un peu le code et notamment en faisant affiché le « $url » et « $http_args », j’ai vu que la requête était sur : https://api.wordpress.org/plugins/info/1.0/

A ce stade, il y a deux soucis :

  • La résolution pour api.wordress.org échoue
  • Le HTTPS ne fonctionne pas

Le problème de résolution DNS

Il manque la plupart des bibliothèques DNS nécessaires à PHP pour faire fonctionner « gethostbyname » par exemple. Après des recherches, j’ai trouvé que les fichiers suivants étaient manquant :

cp -vaR /lib64/libdns-export.so.100.1.1 /lib64/libdns.so.100.1.1 /lib64/libnss_dns-2.17.so .
cd /home/tuto/lib64
ln -s libdns-export.so.100.1.1 libdns-export.so.100
ln -s libdns.so.100.1.1 libdns.so.100
ln -s libnss_dns.so libnss_dns.so.2
ln -s libnss_dns-2.17.so libnss_dns.so

Les noms peuvent changer un peu, sachant que je travaille sous Centos 7.1 lors de la rédaction de ce billet. Globalement, il faut reprendre /lib64/*dns* et refaire les liens symboliques aussi.
Désormais, la partie DNS devrait fonctionner, c’est testable avec ce bout de code :

<?php
print_r(gethostbynamel("toto.com"));
?>

Il faut bien relancer php-fpm après avoir fait tout cela, j’ai passé 20 minutes à ne pas comprendre pourquoi la requête DNS ne se faisait pas à cause de cet oubli …

Le problème avec CURL sur des liens HTTPS (SSL)

C’est le problème avec lequel j’ai passé le plus de temps. Si vous souhaitez juste la solution, sautez quelques paragraphes et lisez en diagonales les commandes.

Déjà, pour comprendre que le problème venait de SSL (car j’avais toujours des doutes sur la partie résolution DNS), j’ai dû modifier un peu le fichier de WordPress (celui cité plus haut) pour forcer le passage en HTTP classique (en modifiant la variable PHP $url directement).
J’ai vu que la requête passait en HTTP mais pas en HTTPS.

Pour comprendre d’où cela venait, j’ai activé le debug de PHP, mais je n’avais pas d’erreurs. J’ai donc utilisé un outil magique qui est : strace.
Cet outil permet d’avoir une idée de ce que fait un processus en cours d’exécution et est très utile dans le genre de cas ou les logs ne disent pas grand choses et qu’on doit observer une « boite noire » en quelque sorte.
Pour faire cela, j’ai donc diminué le nombre de worker php-fpm à 1, afin d’avoir un seul PID. Le strace fonctionne en donnant le PID du processus et avec plusieurs worker c’est délicat d’intercepter le bon.

ps -ef |grep php-fpm
strace -p PID_PROCESSUS 2> logs_

On rafraîchie la page WordPress qui plante et on analyse le fichier de log généré. Généralement je commence par le bas du fichier (souvent ça « plante » vers la fin).
En regardant les logs, des IP sautent aux yeux (donc la résolution DNS se fait bien), voici la partie intéressante isolé du reste :

connect(5, {sa_family=AF_INET, sin_port=htons(443), sin_addr=inet_addr(« 66.155.40.203 »)}, 16) = -1 EINPROGRESS (Operation now in progress)
poll([{fd=5, events=POLLOUT|POLLWRNORM}], 1, 0) = 0 (Timeout)
poll([{fd=5, events=POLLOUT}], 1, 1000) = 1 ([{fd=5, revents=POLLOUT}])
poll([{fd=5, events=POLLOUT|POLLWRNORM}], 1, 0) = 1 ([{fd=5, revents=POLLOUT|POLLWRNORM}])
getsockopt(5, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
getpeername(5, {sa_family=AF_INET, sin_port=htons(443), sin_addr=inet_addr(« 66.155.40.203 »)}, [16]) = 0
getsockname(5, {sa_family=AF_INET, sin_port=htons(59211), sin_addr=inet_addr(« 163.172.12.146 »)}, [16]) = 0
stat(« /etc/pki/nssdb », 0x7ffd8fded480) = -1 ENOENT (No such file or directory)

Premier réflexe, on copie tout ce dossier « pki » puis on fait des recherches sur « nss » également.

cp -vaR /etc/pki /home/tuto/etc/
cp -vaR /lib64/nss /home/tuto/lib64

Pour simplifier un peu les tests et comprendre les dépendances nécessaires à curl, utilisé par WordPress, on va copier l’exécutable curl et ces bibliothèques dans le chroot.
Les dépendances sont plus complexes cette fois, je vous recommande d’utiliser un script pour gérer cela automatiquement (facilement trouvable sur internet, par exemple celui de cyberciti est souvent recommandé). De mon côté, j’ai codé le script car j’avais envie de le faire en bash.

ldd /usr/bin/curl
	linux-vdso.so.1 =>  (0x00007ffd1d5e4000)
	libcurl.so.4 => /lib64/libcurl.so.4 (0x00007f69dc72a000)
	libz.so.1 => /lib64/libz.so.1 (0x00007f69dc514000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f69dc2f7000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f69dbf36000)
	libidn.so.11 => /lib64/libidn.so.11 (0x00007f69dbd03000)
	libssh2.so.1 => /lib64/libssh2.so.1 (0x00007f69dbad8000)
	libssl3.so => /lib64/libssl3.so (0x00007f69db896000)
	libsmime3.so => /lib64/libsmime3.so (0x00007f69db66f000)
	libnss3.so => /lib64/libnss3.so (0x00007f69db348000)
	libnssutil3.so => /lib64/libnssutil3.so (0x00007f69db11c000)
	libplds4.so => /lib64/libplds4.so (0x00007f69daf18000)
	libplc4.so => /lib64/libplc4.so (0x00007f69dad12000)
	libnspr4.so => /lib64/libnspr4.so (0x00007f69daad4000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007f69da8d0000)
	libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007f69da683000)
	libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007f69da3a0000)
	libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007f69da16e000)
	libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007f69d9f69000)
	liblber-2.4.so.2 => /lib64/liblber-2.4.so.2 (0x00007f69d9d5a000)
	libldap-2.4.so.2 => /lib64/libldap-2.4.so.2 (0x00007f69d9b08000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f69dc999000)
	libssl.so.10 => /lib64/libssl.so.10 (0x00007f69d989a000)
	libcrypto.so.10 => /lib64/libcrypto.so.10 (0x00007f69d94b3000)
	librt.so.1 => /lib64/librt.so.1 (0x00007f69d92aa000)
	libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007f69d909b000)
	libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007f69d8e97000)
	libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f69d8c7c000)
	libsasl2.so.3 => /lib64/libsasl2.so.3 (0x00007f69d8a5f000)
	libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f69d8839000)
	libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f69d8602000)
	libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f69d83a1000)
	liblzma.so.5 => /lib64/liblzma.so.5 (0x00007f69d817b000)
	libfreebl3.so => /lib64/libfreebl3.so (0x00007f69d7f78000)

Une fois que cela est fait, on peut déboguer cela en ligne de commande directement :

root home # chroot /home/tuto /bin/curl -v https://google.com
* About to connect() to google.com port 443 (#0)
*   Trying 216.58.211.110...
* Connected to google.com (216.58.211.110) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* Unable to initialize NSS database
* Initializing NSS with certpath: none
* Unable to initialize NSS
* Closing connection 0
curl: (77) Problem with the SSL CA cert (path? access rights?)

On a déjà un peu plus d’information qu’avec PHP.

strace chroot /home/tuto /bin/curl -v https://google.com 2> logs_3

Dans ce strace, quelques éléments sont intéressants :

open(« /proc/sys/crypto/fips_enabled », O_RDONLY) = -1 ENOENT (No such file or directory)
open(« /lib64/libsoftokn3.so », O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
readlink(« /lib64/libnss3.so », 0x137e400, 1023) = -1 EINVAL (Invalid argument)

On ajoute les libs manquantes :

cp /lib64/libsoftokn3.so  /lib64/libnss3.so /etc/alternatives/libnssckbi.so.x86_64 /lib64/libnss_compat-2.17.so /lib64/libnss_compat.so.2 /lib64/libnss_db-2.17.so /lib64/libnss_db.so.2 libnss_db-2.17.so /lib64/libfreeblpriv3.so /lib64/libnss_dns-2.17.so /lib64/libnss_files-2.17.so /lib64/libnss_hesiod-2.17.so /lib64/libnss_myhostname.so.2 /lib64/libnss_nis-2.17.so /lib64/libnss_nisplus-2.17.so /lib64/libnsspem.so /lib64/libnss_sss.so.2 /lib64/libnsssysinit.so /lib64/libnssutil3.so /home/tuto/lib64

Maintenant, vient l’erreur vicieuse qui m’a fait perdre beaucoup de temps. En l’état, ça ne fonctionne toujours pas, car il manque une bibliothèque mais qui n’a aucun rapport avec SSL.

En relance une nouvelle fois un strace et en lisant les logs, on observe que ça progresse, car les erreurs précédentes ne sont plus présentes, par contre, deux nouvelles erreurs apparaissent :

open("/lib64/libsqlite3.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/lib64/libsqlite3.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)

Il manque la bibliothèque « libsqllite3 » qui est nécessaire à NSS car ce dernier manipule des fichiers .db du répertoire /etc/pki/nssdb. J’étais passé totalement à côté de ce détail, pourtant évidant dès qu’on y pense. J’étais concentré sur SSL en me disant qu’il manquait encore des choses.

cp /lib64/libsqlite3.so.0 /lib64/libsqlite3.so.0.8.6 tuto/lib64/
chroot /home/tuto /bin/curl -v https://google.com
* About to connect() to google.com port 443 (#0)
*   Trying 216.58.211.110...
* Connected to google.com (216.58.211.110) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSL connection using TLS_RSA_WITH_AES_128_CBC_SHA
* Server certificate:
* 	subject: CN=*.google.com,O=Google Inc,L=Mountain View,ST=California,C=US
* 	start date: Oct 21 21:35:50 2015 GMT
* 	expire date: Jan 19 00:00:00 2016 GMT
* 	common name: *.google.com
* 	issuer: CN=Google Internet Authority G2,O=Google Inc,C=US
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: google.com
> Accept: */*
>
< HTTP/1.1 302 Found
< Cache-Control: private
< Content-Type: text/html; charset=UTF-8
< Location: https://www.google.fr/?gfe_rd=cr&ei=zCM1VuH6LrOx8we2pqHICg
< Content-Length: 259
< Date: Sat, 31 Oct 2015 20:25:48 GMT
< Server: GFE/2.0
< Alternate-Protocol: 443:quic,p=1
< Alt-Svc: quic=":443"; p="1"; ma=604800
<
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="https://www.google.fr/?gfe_rd=cr&amp;ei=zCM1VuH6LrOx8we2pqHICg">here</A>.
</BODY></HTML>
* Connection #0 to host google.com left intact

Conclusion

J’espère vous avoir montré deux choses dans cet article, la première étant de voir comment il est possible d’avoir un SSL fonctionnel dans un environnement chrooté et la deuxième, la plus importante pour moi, est l’utilisation de strace. C’est un outil à connaitre et à utiliser lorsque les logs ne parlent pas beaucoup. Il est très verbeux par contre, vous avez des options pour limiter l’affichage éventuellement.

J’ai tout fait « manuellement » dans cet article car je suis encore dans une phase d’apprentissage pour php-fpm et son option de chroot, je veux bien comprendre le mécanisme et éviter de copier/coller bêtement des choses trouvables sur internet.
Si vous voulez faire cela, sachez qu’il existe pas mal d’outils pour automatiser tout cela, notamment pour la partie avec « ldd » (par exemple celui-ci).

Si vous avez des idées, des remarques sur la partie SSL, chroot (encore un peu nouveau pour moi !) ou strace n’hésitez pas à partagez cela dans les commentaires.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *