HAProxy im mode tcp und der Kombination Ubuntu 18.04 LTS mit Apache als Backend Server hat einen entscheidenden Nachteil, wenn damit die ursprüngliche Client IP im Apache Logfile aufgezeichnet werden soll. Um dies zu bewerkstelligen ist das Proxy Protokoll zu verwenden. Allerdings ist die Unterstützung des HAProxy Proxy Protokolls in den Apache erst mit der Version 2.4.30 erfolgt. Ein auf GitHub entwickeltes Apache Modul mod-proxy-protocol wurde wie dort beschrieben in das Modul mod_remoteip des Apache Projektes gemerged.
In Ubuntu 18.04 LTS steht der Apache allerdings nur in der Version
:~# apache2 -v Server version: Apache/2.4.29 (Ubuntu) Server built: 2018-04-25T11:38:24
zur Verfügung und in diesem ist das Module mod_remoteip nicht mit der beschriebenen Proxy Protokoll Unterstützung enthalten.
:~# a2enmod remoteip Enabling module remoteip. To activate the new configuration, you need to run: systemctl restart apache2.service :~# vim sites-enabled/000-default.conf [...] RemoteIPProxyProtocol On [...] :~# apache2ctl configtest AH00526: Syntax error on line 8 of /etc/apache2/sites-enabled/000-default.conf: Invalid command 'RemoteIPProxyProtocol', perhaps misspelled or defined by a module not included in the server configuration Action 'configtest' failed. The Apache error log may have more information.
Ein Ausweg kann sein, das Modul mod_remoteip aus der stabilen Apache Version, zur Zeit 2.4.33, selbst zu kompilieren und einzubinden. Den Source Code des Modules kann man sich aus dem kompletten Download des Apache httpd-<version>.tar.gz oder entsprechd des SVN herausholen. Der Code findet sich unter dem Pfad.
./modules/metadata/mod_remoteip.c
Zum Kompilieren müssen die Apache Developer-Tools installiert sein. Dies sollte evtl. auf einer eigenen Ubuntu 18.04 LTS VirtualBox VM geschehen. Damit ist sichergestellt, dass das Original Modul nicht überschrieben wird.
:~# apt-get install apache2-dev [...]
Kompilieren des Moduls mittels apxs2.
:~# apxs2 -c -i mod_remoteip.c /usr/share/apr-1.0/build/libtool --mode=compile --tag=disable-static x86_64-linux-gnu-gcc -prefer-pic -pipe -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -DLINUX -D_REENTRANT -D_GNU_SOURCE -pthread -I/usr/include/apache2 -I/usr/include/apr-1.0 -I/usr/include/apr-1.0 -I/usr/include -c -o mod_remoteip.lo mod_remoteip.c && touch mod_remoteip.slo libtool: compile: x86_64-linux-gnu-gcc -pipe -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -DLINUX -D_REENTRANT -D_GNU_SOURCE -pthread -I/usr/include/apache2 -I/usr/include/apr-1.0 -I/usr/include/apr-1.0 -I/usr/include -c mod_remoteip.c -fPIC -DPIC -o .libs/mod_remoteip.o /usr/share/apr-1.0/build/libtool --mode=link --tag=disable-static x86_64-linux-gnu-gcc -Wl,--as-needed -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -o mod_remoteip.la -rpath /usr/lib/apache2/modules -module -avoid-version mod_remoteip.lo libtool: link: rm -fr .libs/mod_remoteip.la .libs/mod_remoteip.lai .libs/mod_remoteip.so libtool: link: x86_64-linux-gnu-gcc -shared -fPIC -DPIC .libs/mod_remoteip.o -Wl,--as-needed -Wl,-Bsymbolic-functions -Wl,-z -Wl,relro -Wl,-z -Wl,now -Wl,-soname -Wl,mod_remoteip.so -o .libs/mod_remoteip.so libtool: link: ( cd ".libs" && rm -f "mod_remoteip.la" && ln -s "../mod_remoteip.la" "mod_remoteip.la" ) /usr/share/apache2/build/instdso.sh SH_LIBTOOL='/usr/share/apr-1.0/build/libtool' mod_remoteip.la /usr/lib/apache2/modules /usr/share/apr-1.0/build/libtool --mode=install install mod_remoteip.la /usr/lib/apache2/modules/ libtool: install: install .libs/mod_remoteip.so /usr/lib/apache2/modules/mod_remoteip.so libtool: install: install .libs/mod_remoteip.lai /usr/lib/apache2/modules/mod_remoteip.la libtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/sbin" ldconfig -n /usr/lib/apache2/modules ---------------------------------------------------------------------- Libraries have been installed in: /usr/lib/apache2/modules If you ever happen to want to link against installed libraries in a given directory, LIBDIR, you must either use libtool, and specify the full pathname of the library, or use the '-LLIBDIR' flag during linking and do at least one of the following: - add LIBDIR to the 'LD_LIBRARY_PATH' environment variable during execution - add LIBDIR to the 'LD_RUN_PATH' environment variable during linking - use the '-Wl,-rpath -Wl,LIBDIR' linker flag - have your system administrator add LIBDIR to '/etc/ld.so.conf' See any operating system documentation about shared libraries for more information, such as the ld(1) and ld.so(8) manual pages. ---------------------------------------------------------------------- chmod 644 /usr/lib/apache2/modules/mod_remoteip.so
Das so entstandene Binary sollte unter anderem Namen auf die „produktiv“ Maschine kopiert werden.
:~# mv /usr/lib/apache2/modules/mod_remoteip.so mod_remoteip_2433.so :~# scp mod_remoteip_2433.so /usr/lib/apache2/modules/
Damit ist sichergestellt, dass das Modul bei einem apt-get update/upgrade Lauf niemals überschrieben wird.
Einbinden des selbskompilierten Modules in die Apache Konfiguration.
:~# cd /etc/apache2 :~# vim mods-available/remoteip_2433.load LoadModule remoteip_module /usr/lib/apache2/modules/mod_remoteip_2433.so :~# a2enmod remoteip_2433 Enabling module remoteip_2433. To activate the new configuration, you need to run: systemctl restart apache2.service :~# apache2ctl configtest Syntax OK :~# systemctl restart apache2.service
Der Vorteile des Proxy Protokolls liegt nun darin, dass die zugreifenden Client IPs über den HAProxy im mode tcp an den Apache übermittelt werden und diese in die Logfiles der Apache Backend Server mit aufgenommen werden können. Dazu ist noch eine kleine Erweiterung am Logfile Format um ein %a vorzunehmen.
:~# vim apache2.conf [...] LogFormat "%a %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
In der HAProxy Konfiguration wird nun ebenfalls das Proxy Protokoll per send-proxy eingeschaltet.
:~# vim /etc/haproxy/haproxy.cfg [...] frontend frontend227 description Frontent 227 mode tcp option tcplog bind 192.168.202.227:80 default_backend backend227 backend backend227 description Backend 227 mode tcp server web01 192.168.56.227:80 send-proxy check :~# haproxy -f /etc/haproxy/haproxy.cfg -c Configuration file is valid :~# systemctl restart haproxy
Testzugriff per curl oder Browser und die Kontrolle der entsprechenden Logfiles der HAProxy und Apache Backend Servers.
:~$ curl http://192.168.202.227/ :~# tail -f /var/log/haproxy.log May 13 19:54:17 haproxy01 haproxy[1848]: 192.168.202.246:50191 [13/May/2018:19:54:17.923] frontend227 backend227/web01 1/0/2 229 -- 2/1/0/0/0 0/0 :~# tail -f /var/log/apache2-227/access.log 192.168.202.246 192.168.56.225 - - [13/May/2018:19:54:18 +0200] "GET / HTTP/1.1" 200 229 "-" "curl/7.47.0"
Die 192.168.202.246 ist die zugreifende IP des Client.