Afficher les ip de connexion dans les logs apache derrrière haproxy
Rédigé par Marc GUILLAUME | 2 commentairesLa page de la doc Apache concernant le mode remoteip :
https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html
Haproxy fonctionnant comme un reverseproxy, quand un serveur Apache est accédé via haproxy, l'IP qui apparaît dans les logs est celle du haproxy, ce qui est gênant puisqu'ainsi on n'a aucune information sur l'IP du visiteur.
Pour éviter ce défaut il convient d'utiliser une option dans le fichier de configutation de Haproxy et d'activer le mod_remoteip d'Apache. Voici comment faire :
Configuration de haproxy.cfg
L'option permettant de renvoyer l'IP du visiteur au serveur web est :
option forwardfor
Cette option doit être placée dans le blod defaults et dans chaque frontend. Un bloc defaults typique se présente ainsi :
defaults log global mode http option httplog option forwardfor except 127.0.0.1 option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 errorfile 400 /etc/haproxy/errors/400.http errorfile 403 /etc/haproxy/errors/403.http errorfile 408 /etc/haproxy/errors/408.http errorfile 500 /etc/haproxy/errors/500.http errorfile 502 /etc/haproxy/errors/502.http errorfile 503 /etc/haproxy/errors/503.http errorfile 504 /etc/haproxy/errors/504.http
L'option est en gras. Pour un bloc frontend :
frontend unsecure bind *:80 default_backend mybackend option forwardfor
Configuration côté apache
Récupérer l'IP de l'internaute
Pour cela dans Apache nous allons avoir à faire trois choses. Activer le module mod_remoteip qui permet de renvoyer l'IP du visiteur que Haproxy fait passer dans une entête (header) HTTP_X_FORWARDED_FOR dans la variable classique REMOTE_IP.
a2enmod remoteip
Dans un deuxième temps nous allons créer une configuration dans /etc/apache2/conf-available/
qui contiendra la directive indiquant qu'il faut activer la modification d'IP. Pour ce faire on crée un fichier qui va par exemple s'appeller haproxyIP.conf et l'on va placer dedans l'option RemoteIPHeader X-Forwarded-For :
echo "RemoteIPHeader X-Forwarded-For" > /etc/apache2/conf-available/haproxyIP.conf
Puis l'activer :
a2enconf haproxyIP
Il reste à adapter le format de log. Nous postulerons ici que nous utilisons le mode combined. Dans /etc/apache2/apache2.conf
recherchez ces lignes (vers la fin du fichier sur une installation fraîche) :
# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended. # Use mod_remoteip instead. # LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %O" common LogFormat "%{Referer}i -> %U" referer LogFormat "%{User-agent}i" agent
Nous reparlerons de la ligne de commentaire qui se situe avant la définition des formats de log.Pour l'instant nous allons modifier la ligne se terminant par combined.
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
Le %h est remplacé par %a qui est la variable utilsée par mod_remoteip comme indiqué dans la documentation. Il ne reste plus qu'à redémarrer apache :
systemctl restart apache2
Maintenant dans les logs d'apache apparaissent les IP des visiteurs en lieu et place de celle d'Haproxy.
Pour revenir sur la remarque concernant %{X-Forwarded-For}i cette syntaxe, en n'utilisant pas mod_remoteip est souvent indiquée dans le tutos d'Internet mais on doit maintenant lui préférer l'utilisation du mode apache adapté comme indiqué dans le commentaire.
Récupérer le protocol https depuis haproxy
Si votre haproxy est configuré pour servir les certificats ssl des noms de domaine, il contacte généralement ses backends en http (port 80). Il faut donc, si la redirection https n'est pas forcée sur haproxy, qu'Apache puisse savoir si il a été contacté en http ou https.
De nombreux cms comme prestashop utilisent la variable d'environnement HTTPS d'apache. Mais derrière haproxy cette variables n'est jamais à on puisque la connexion se fait en http. En revanche une autre variable d'environnement fournie par Haproxy donne l'information, la variable HTTP_X_FORWARDED_PROTO qui prend la valeur https si la connexion de l'internaute se fait en https.
Il faut donc que nous créions une directive, un peu sur le modèle de celle pour l'IP, qui mette la variable HTTPS à on si le protocole transmis est https. Nous allons créer toujours dans /etc/apache2/conf-available/
un fichier que nous allons choisir de nommer haproxyHTTPS.conf. Et nous allons utiliser la directive SetEnvIf d'Apache qui est justement faite pour modifier une variable d'environnement sous une certaine condition. Ici la condition est que le proctocole retransmis (forwarded) soit https :
echo "SetEnvIf X-Forwarded-Proto https HTTPS=on" > /etc/apache2/conf-available/haproxyHTTPS.conf
Il ne restera plus qu'à l'activer :
a2enconf haproxyHTTPS
puis à recharger apache2
systemctl reload apache2
Maintenant la variable HTTPS apache vaudra on si le protocol transmis est https.