Je dispose de plusieurs serveurs web Apache, répartis dans des machines virtuelles. Afin d’aiguiller le traffic http selon certain critères (entête http Host: par exemple) vers ces divers serveurs, j’utilise un reverse proxy en frontal, à savoir Pound. (si vous cherchez un reverse proxy libre et léger, foncez !)
Un problème se pose: dans les logs des serveurs Apache, c’est l’ip du frontal qui apparaît, l’analyse des logs présente alors peu d’intérêt, car tout le trafic semble venir du frontal !
192.168.0.1 – - [07/Mar/2009:04:25:16 +0100] “GET / HTTP/1.0″ 200 31787 “-”
En fait, il est possible de faire apparaître l’ip du client à l’origine de la requête, au prix de quelques modifications autour du traitement de l’entête http X-Forwarded-for
Cette entête http permet d’identifier le client originel dont la requête est passée au travers d’un proxy ou d’un répartiteur de charge, et il se trouve que Pound rajoute cette entête avant de passer la requête aux serveurs web derrière lui.
La configuration par défaut des logs d’Apache ne récupérant pas cette entête, il faut se créer un LogFormat personnalisé récupérant cette information.
Voici le mien, que j’appelle combined_proxy:
LogFormat “%{X-Forwarded-For}i %l %u %t \”%r\” %>s %b \”%{Referer}i\” \”%{User-Agent}i\”" combined_proxy
D’où ça sort ? Explications : c’est le LogFormat par défaut d’Apache que voici :
LogFormat “%h %l %u %t \”%r\” %>s %b \”%{Referer}i\” \”%{User-Agent}i\”" combined
dans lequel j’ai remplacé le %h qui est le remote host (plus d’infos ici) par une variable
%{Foobar}i
, où Foobar est une entête de la requête http. Comme ce n’est pas l’entête Foobar qui m’intéresse mais X-Forwarded-For, il suffit de remplacer
Maintenant dans votre configuration Apache, il faut utiliser ce LogFormat à la place du standard dans les directives CustomLog, ce qui donne ceci :
CustomLog /var/log/apache2/access.log combined_proxy
C’est tout ! Voici maintenant l’ip du client dans les logs des serveurs Apache:
72.14.221.104 – [07/Mar/2009:08:05:56 +0100] “GET / HTTP/1.0″ 200 31787 “-”
Dernière subtilité : que se passe-t-il si la requête venant au reverse proxy contient déjà l’entête X-Forwarded-For ? Eh bien Pound rajoute à l’entête l’ip du frontal, comme décrit dans la doc, les logs contiendront donc les 2 ip:
192.168.0.1, 72.14.221.104 – - [07/Mar/2009:09:03:57 +0100] “GET / HTTP/1.0″ 200 31787 “-”
Ici on comprend que le proxy 74.14.221.104 a fait transiter la requête du client 192.168.0.1
Comme ca ne m’intéresse pas de connaître la liste des proxy traversés par le client, le plus simple est, au niveau du frontal, du supprimer cette entête si elle existe déjà.
Avec Pound, la directive HeadRemove permet de supprimer des entêtes http. Elle se place dans la directive ListenHTTP :
ListenHTTP
Address 127.0.0.1
Port 80
HeadRemove “X-Forwarded-For”
Service
HeadRequire “Host: .*foo.com.*”
BackEnd
Address 192.168.0.1
Port 80
End
End
End
Maintenant, on retrouve dans les logs Apache les informations désirées :
72.14.221.104 – - [07/Mar/2009:09:03:57 +0100] “GET / HTTP/1.0″ 200 31787 “-”