Source IP tracking

Dans le cadre d’un environnement web haute disponibilité il y a généralement des répartiteurs de charge HTTP comme HAproxy ou des reverse proxies comme Apache ou Nginx en frontal qui vont s’occuper de répartir la charge et/ou filtrer une partie des requêtes pour ménager les serveurs d’application de backend.

Le principal problème rencontré dans ce type d’architecture est que, généralement, le service web de frontend va masquer l’IP source du client, réduisant la tracabilité de celui-ci sur les backends. Nous allons ici partir du principe que le service web de frontend retransmet l’IP au backend via un en-tête HTTP nommé X-Real-IP.

L’astuce que nous allons voir ici permet d’afficher l’adresse IP du client via l’en-tête X-Real-IP si celui-ci existe, auquel cas l’adresse IP source.

Dans un premier temps nous allons définir 2 LogFormat, _completerealip et complete, chacun ayant un paramétrage sur le champ 1 différent:

LogFormat "%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{Host}i\" %D" complete_realip
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{Host}i\" %D" complete

Dans un second temps, nous allons nous servir du module _modsetenvif afin de vérifier l’existence de l’en-tête:

SetEnvIf X-Real-IP ^.+$ real_ip_exists

Enfin on définit une condition sur l’environnement afin de basculer le log d’un mode à l’autre suivant la requête entrante:

CustomLog /var/log/apache/myapp_access.log complete_realip env=real_ip_exists
CustomLog /var/log/apache/myapp_access.log complete env=!real_ip_exists

Conclusion

Votre serveur Apache va désormais basculer l’IP présentée dans ses logs dynamiquement en fonction de la présence ou non de l’en-tête X-Real-IP.

Note: Si vous utilisez un haproxy en frontend, la configuration à ajouter à vos backend haproxy est la suivante:

http-request set-header X-Real-IP %[src]

See Also