Haproxy Apache2 X Forwarded For
Haproxy en frontend et Apache2 en backend
Il y a peu j’ai fait l’acquisition d’un petit serveur à la maison. L’objectif était de remettre quelques services non critiques sur celui-ci.
Le setup est le suivant : j’ai un haproxy qui écoute sur les ports 80/TCP et 443/TCP. Les sites web sont sur une machin virtuelle où il y a un apache2 qui est configuré pour répondre aux différents sites web. J’ai décidé d’utiliser haproxy alors que j’aurais pu reprendre mes anciennes configurations à base de nginx. Pourquoi ? Afin d’approfondir et d’apprendre mieux haproxy que je trouve très chouette au passage.
On peut se représenter ainsi le flux : utilisateur -> haproxy (80/TCP) -> haproxy (443/TCP) -> VM Linux avec Apache2.
Du coup je me suis donc lancé dans la configuration de haproxy. J’ai plusieurs sites web qui sont hébergés sur la même VM donc j’ai tenté de voir s’il était possible de factoriser la configuration de haproxy, la réponse est oui. D’ailleurs ma configuration n’est pas encore optimale mais faut ce que je veux pour le moment.
Ainsi, dans le répertoire /etc/haproxy j’ai créé le fichier websites.map qui permet de faire de la correspondance entre un vhost et un backend haproxy.
Concrètement cela ressemble à :
root@betelgeuse:/etc/haproxy# cat websites.map
hindy.lovetux.net bk_hindy
matrix.lovetux.net bk_matrix
root@betelgeuse:/etc/haproxy#
Puis la configuration que j’ai mis en place dans /etc/haproxy/haproxy.cfg est la suivante :
frontend websites
bind *:80
bind :443 ssl crt /etc/haproxy/ssl/lovetux.net.pem
http-request redirect scheme https unless { ssl_fc }
mode http
option forwardfor
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
use_backend %[req.hdr(host),lower,map_dom(/etc/haproxy/websites.map,bk_default)]
backend bk_hindy
mode http
server web-soli 192.168.69.1:80
backend bk_matrix
mode http
server web-soli 192.168.69.1:8008
On notera plusieures choses importantes dans cette configuration :
- l’utilisation de l’option http-request qui permet de forcer la redirection HTTP vers HTTPS ;
- le fait que l’on souhaite indiquer l’utilisation de l’entête forwardfor ;
- l’utilisation de notre fichier map (/etc/haproxy/websites.map).
Côté Apache la configuration est plutôt aisée, ainsi voici un fichier de configuration de vhost :
<VirtualHost 192.168.69.1:80>
ServerName hindy.lovetux.net
DocumentRoot /srv/sites/hindy/hindy.lovetux.net
<Directory /srv/sites/hindy/hindy.lovetux.net>
Require all granted
AllowOverride all
Options -Indexes
</Directory>
ErrorLog /var/log/apache2/hindy.lovetux.net.error.log
CustomLog /var/log/apache2/hindy.lovetux.net.access.log combined
</VirtualHost>
Du très très classique.
Puis ensuite j’ai commencé à regarder les logs côté Apache et j’avais complètement oublié que l’adresse IP qui serait remontée serait celle locale et non l’adresse IP du client source. Etant donné que haproxy est correctement configuré et qu’il comporte la direction option forwardfor, il convient donc de regarder la configuration côté Apache.
Sur ma Debian 10 j’ai ainsi modifié le fichier /etc/apache2/apache2.conf.
Initialement il y a cette ligne :
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
Nous remplaçons cette ligne par :
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
On constate que c’est presque la même ligne mais au caractère %a qui est utilisé. Ainsi, maintenant nos logs apache contiennent l’adresse IP cliente.