Nach deutschem Datenschutzrecht ist die anlasslose Speicherung personenbezogener Daten unzulässig. Zu diesen Daten gehört auch die IP-Adresse eines jeden Webseiten Besuchers die vermutlich trotzdem von einer sehr großen Anzahl an Webservern im Access-Log protokolliert wird.
Nur, was tun um hier datenschutzkonform zu sein?
In einigen Artikeln wird empfohlen ein Custom-Log Format einzusetzen und dabei die Client-IP wegzulassen. Beim Nginx als Beispiel wird die IP-Adresse in der Variable $remote_addr gespeichert, beim Apache ist dies %a und beim Haproxy %Ci. Dieser recht pragmatische Ansatz ist sicher datenschutzkonform, hat jedoch den entscheidenden Nachteil, dass wir keinerlei Informationen mehr über die Herkunft unserer Webseiten-Besucher haben. Wäre es daher nicht sinnvoll zumindest die Netzwerk-Adresse zu speichern um so Rückschlüsse zur Täterermittlung bei einem Angriff auf unsere Infrastruktur an der Hand zu haben?
Das Speichern der kompletten IP-Adresse ist daher nicht rechtens, weil mit Wissen eines Dritten – in dem Fall des Providers – ein eindeutiger Personenbezug hergestellt werden kann.
Anonymisieren wir nun aber Teile der IP-Adresse gilt dies als rechtmäßig. Genau dieses Verfahren kann bei den Webseiten-Analyze Tools, Piwik und Google Analytics konfiguriert werden. Bei der Anonymisierung wird in der Regel das letzte Oktet einer IPv4 Adresse bzw. die letzten beiden Oktete maskiert. So wird aus 192.168.1.10 nach der Anonymisierung 192.168.1.0 bzw. 192.168.0.0.
Zu diesem Zweck gibt es für den Apache Webserver das Modul mod_anonip.Die Konfiguration ist simpel, mit dem Parameter AnonipMask = 2 werden die beiden letzten Bytes der IP-Adresse mit 0.0 maskiert.
Nur leider ist Apache hier ziemlich alleine, weder für den Nginx Webserver noch für den Haproxy Loadbalancer gibt es ein solches Modul. Da beide Dienste aber an Syslog loggen (und Haproxy das per Default sogar schon tut), schafft das (r)syslogd Module mmanon hier Abhilfe.
Schauen wir uns zuerst Haproxy an. Nach der Installation von Haproxy 1.5 auf einem Debian 8 System finden wir die Logging-Konfiguration in: /etc/rsyslog.d/49-haproxy.conf wieder:
# Create an additional socket in haproxy's chroot in order to allow logging via
# /dev/log to chroot'ed HAProxy processes
$AddUnixListenSocket /var/lib/haproxy/dev/log
# Send HAProxy messages to a dedicated logfile
if $programname startswith 'haproxy' then /var/log/haproxy.log
&~
Diese Konfiguration wird wie folgt geändert:
# Create an additional socket in haproxy's chroot in order to allow logging via
# /dev/log to chroot'ed HAProxy processes
$AddUnixListenSocket /var/lib/haproxy/dev/log
$ModLoad mmanon
# Send HAProxy messages to a dedicated logfile and anonymize the last octet of the ip-adress
if $programname startswith 'haproxy' then { action(type="mmanon" ipv4.bits="8") action(type="omfile" file="/var/log/haproxy.log") stop }
Das Module wird über $ModLoad mmanon geladen die Action sorgt dafür, dass das letzte Oktet (ipv4.bits=“8″) maskiert wird. Nach der Änderung ist ein Restart des Rsyslog-Daemons nötig.
Nginx kann erst seit Version 1.7 via Syslog loggen. Der in Debian enthaltene 1.6er Server ist demnach für das folgende Beispiel nicht geeignet. Ich empfehle hier die Verwendung des Dotdeb-Repositories und die Installation eines Nginx 1.8.
In der Konfigurations-Datei: /etc/nginx/nginx.conf werden die beiden Einträge für das Logging wie folgt geändert:
access_log syslog:server=unix:/dev/log,tag=nginx_access;
error_log syslog:server=unix:/dev/log,tag=nginx_error;
Eine entsprechende Rsyslog-Konfiguration hinterlegen wir in: /etc/rsyslog.d/99-nginx.conf
# Load IP Anonymize Module
$ModLoad mmanon
# Send HAProxy messages to a dedicated logfile and anonymize the last octet of the ip-adress
if $msg startswith ' nginx_access' then { action(type="mmanon" ipv4.bits="8") action(type="omfile" file="/var/log/nginx/access.log") stop }
if $msg startswith ' nginx_error' then { action(type="mmanon" ipv4.bits="8") action(type="omfile" file="/var/log/nginx/error.log") stop }
Nach einem Restart vom Nginx und Rsyslogd finden wir in beiden Logs nur noch die maskierten IP-Adressen wieder. Dem aufmerksamen Leser wird nicht entgangen sein, dass im Nginx zwar ein Tag nginx_access gesetzt wird, in der Rsyslog-Konfiguration aber in der Nachricht ($msg) auf diesen String geprüft wird. Dies liegt an einem Bug der den Hostnamen doppelt loggt, damit rutscht der zweite Hostname an die Stelle des Tags, der eigentlich Tag aber in den Bereich der Log-Meldung. In Nginx 1.9 gibt es eine Option nohostname mit dem genau das verhindert werden kann.
Mit dem Modul mmanon haben wir ein Werkzeug an der Hand, mit dem die Logfiles aller Dienste (denkbar wären auch FTP- und Maillogs) datenschutzkonform gespeichert werden können.