blog.bartlweb - a technologist's external brain

IP-Adressen in Access- und Error-Logs des Apache Webserver anonymisieren

Wer das Thema Datenschutz seiner Nutzer ernst nimmt, weiß das auch die IP-Adresse des Nutzers zu seinen schutzwürdigen persönlichen Daten zählt. Die Kombination einer IP-Adresse und die Parameter einer Anfrage an den Server (z.B. bei einer Suche) lassen dann bereits Rückschlüsse auf das Nutzungsverhalten bestimmter Personen zu und genau das wollen wir vermeiden.

Der Apache Webserver bietet bereits von Haus aus die Möglichkeit das Format der Log-Datei für Zugriffe über seine Einstellungen anzupassen. Allerdings gibt es erstens nur die Möglichkeit die IP-Adresse ganz wegzulassen und zweitens kann nur das Format der Access Logs (Zugriffe), aber nicht der Error Logs (Fehler) angepasst werden.

Gerade zum Debugging macht es aber auch Sinn die IP-Adresse nur zu anonymisieren und nicht ganz auszublenden. Ein kleines Perl-Skript der "Zentrale Datenschutzstelle der baden-württembergischen Universitäten" (ZENDAS) erlaubt in Verbindung mit einigen wenigen Anpassungen der Apache-Konfiguration genau das. Und zusätzlich werden durch das Skript auch gleich alle URL-Parameter der einzelnen Requests abgeschnitten, um zur Sicherheit auch problematische Werte oder Session-IDs aus den Logs zu verbannen.

Anpassungen an der Apache-Konfiguration

In der Apache-Konfiguration sind einige Anpassungen zu machen, um einerseits ein Daten sparendes Logformat zu definieren und andererseits die Ausgabe der Logs so zu konfigurieren, dass beim Schreiben der Logs das untere Anonymisierungs-Skript eingebunden wird. Die unteren Konfigurationsempfehlungen nutzen den Pfad /opt/aplog-anon.pl - passen Sie diesen Pfad bei Bedarf entsprechend an.

httpd.conf

In der Konfigurationsdatei httpd.conf - die für eigene Konfigurationen vorgesehen ist - werden zwei zusätzliche Log-Formate definiert, die dann für das neue Daten sparende Logging verwendet werden, denn diese sind so gestaltet, dass nur die notwendigsten Informationen geloggt werden.

Wer mehr über die einzelnen Parameter der Log-Formate wissen will, kann diese in der Apache-Dokumentation unter httpd.apache.org/docs/current/mod/mod_log_config.html nachschlagen.

LogFormat "%a - %v:%p - %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" vhost_anonymized
LogFormat "%a - - %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" anonymized

Wer den Datenschutz noch einmal genauer nehmen möchte, kann zusätzlich noch auf das Loggen des User-Agents verzichten. Dazu einfach den entsprechenden Parameter \"%{User-Agent}i\" aus den obigen Konfigurationszeilen entfernen.

apache2.conf

In der Basiskonfigurationsdatei apache2.conf, stellen wir sicher, dass allgemeiner Fehlerlogs anonymisiert werden. Dazu wird die folgende Zeile:

ErrorLog ${APACHE_LOG_DIR}/error.log

durch diese ersetzt:

ErrorLog "|/opt/aplog-anon.pl ${APACHE_LOG_DIR}/error.log"

other-vhosts-access-log.conf

Damit Zugriffe auf virtuelle Hosts die keine eigene Logdatei definieren, ebenfalls anonymisiert werden, müssen wir in der Datei other-vhosts-access-log.conf die Zeile:

CustomLog ${APACHE_LOG_DIR}/access.log vhost_combined

gegen die Folgende ersetzen:

CustomLog "|/opt/aplog-anon.pl ${APACHE_LOG_DIR}/access.log" vhost_anonymized

Konfigurationsdateien der virtuellen Hosts

Das eigentliche Logging bei Zugriffen auf einzelne Hosts wird in den jeweiligen Konfigurationsdateien der virtuellen Hosts definiert. Stellen Sie sicher, dass der Platzhalter <vhost> in den unteren Konfigurationszeilen durch eine eindeutige Bezeichnung Ihres vHosts zu ersetzen, um für jeden vHost eine getrennte Log-Datei zu erstellen.

CustomLog "|/opt/aplog-anon.pl ${APACHE_LOG_DIR}/<vhost>.log" anonymized
ErrorLog "|/opt/aplog-anon.pl ${APACHE_LOG_DIR}/<vhost>.error.log"

Das Anonymisierungs-Skript

Das folgende Skript wurde durch ZENDAS (Zentrale Datenschutzstelle der baden-württembergischen Universitäten) erstellt und ist im Originalen hier zu finden: www.zendas.de/technik/sicherheit/apache/index.html

Das unten stehende Skript ist das Schlüsselelement der ganzen geänderten Konfiguration von oben. Den ab sofort schleust Apache alle Logging-Vorgänge durch den in der Konfiguration angegebenen Pipe-Parameter zuerst an das Skript und erst dann werden diese in die eigentliche Log-Datei geschrieben. So kann das Skript jeden Logeintrag zunächst bearbeiten und damit anonymisieren.

#!/usr/bin/perl
# aplog-anon -- Real-Time-Anonymisierung von Apache-Log-Daten
# Copyright (C) 2003 by Z E N D A S, Universität Stuttgart.
#
# ZENDAS bemüht sich, die Richtigkeit und Funktionsfähigkeit der 
# bereitgestellten Skripte zu gewährleisten. Wir können jedoch nicht dafür 
# einstehen, dass die Skripte auch auf Ihren Systemen auf Anhieb ohne 
# Probleme laufen oder Ihr Server nach Installation der Skripte zusätzlichen 
# Konfigurationsaufwand erfordert und/oder zeitweise nicht einsetzbar ist.
# ZENDAS erklärt sich ausdrücklich für Schäden jeglicher Art, die
# Ihnen, Ihrem Computer oder jeglicher dritten Person oder Sache durch die
# Nutzung oder den Missbrauch dieser Skripte entstehen könnten,
# nicht verantwortlich. Sie nutzen diese Skripte ausdrücklich auf eigenes
# Risiko.
#
#
# Die Anonymisierung dier Client-Adressen wird auf /16er-Netzmasken
# durchgeführt. Eine andere Möglichkeit wären /24er-Netzmasken, aber
# dadurch ist nicht völlig sichergestellt, daß der Personenbezug
# verloren geht. Zusätzlich wird der Referer-URL beim ersten "?"
# abgeschnitten.
#
# In der allgemeinen Apache-Konfiguration ist folgende Zeile einzufügen:
#
# LogFormat "%a - - %t \"%r\" %>s %b \"%{Referer}i\"" combined
#
# In der Konfiguration für virtuelle Server wird das Logging wie folgt
# aktiviert:
#
# ErrorLog "|/path/to/aplog-anon /path/to/error_log"
# CustomLog "|/path/to/aplog-anon /path/to/access_log" combined
#
# Änderungen an den Skripten für die Log-Rotation sind üblicherweise
# nicht erforderlich. Das Logging über eine Pipe erfordert ein paar
# zusätzliche Context Switches; dies sollte aber nur unter absolutem
# Hochlastbetrieb ein Problem darstellen; das Anonymsieren
# funktioniert auf Hardware aus dem Jahr 2002 auch bei mehreren
# Requests pro Sekunde ohne Probleme.
#
# Vorsicht: aplog-anon schreibt typischerweise die Log-Datei mit
# root-Rechten.
 
use strict;
use warnings;
 
use IO::Handle;
 
if (@ARGV != 1) {
  exit 1;
}
 
my $LOG;
open $LOG, ">>$ARGV[0]";
 
# Daten sofort in die Zieldatei schreiben, ohne Pufferung auf Perl-Seite.
$LOG->autoflush(1);
 
while (my $Line = <STDIN>) {
  chomp $Line;
 
  # Das ist eine krude Annäherung an einen richtigen Parser. Sie
  # erwischt im Prinzip alles, was gültige Requests sind. Vom
  # Referer wird alles nach dem ersten "?" weggeschnitten, um das
  # Logging einer Session-ID zu vermeiden.
 
  # Der erste Fall behandelt Fehlermeldungen, die eine andere Syntax
  # haben.
  if ($Line =~ /^\[.*/) {
    $Line =~ s/^(.*?\[client \d+\.\d+)\.\d+\.\d+(\].*)/$1.0.0$2/;
  } else {
    $Line =~ s/^(\d+\.\d+)\.\d+\.\d+ (.*" (?:\d+|-) (?:\d+|-) "[^?]*).*/$1.0.0 $2\"/;
    $Line =~ s/""$/\"/;
  }
 
  print $LOG "$Line\n";
}
 
######################################################################

Dieser Artikel hat Dir deinen Tag gerettet?

... und mühevolles Probieren, Recherchieren und damit Stunden an Zeit gespart? Oder einfach nur Dein Problem gelöst?

Dann würde ich mich freuen, wenn Du meine Zeit für die Erstellung dieses Blogartikels mit einer kleinen Anerkennung honorierst:

Zahlung mit PayPal oder Kreditkarte.

Hinweis zur Verwendung

Die Übermittlung einer Zahlung ist eine persönliche Anerkennung Ihrerseits an den Entwickler (Christian Bartl, Privatperson). Eine Zahlung ist nicht zweckgebunden und es ist keine Gegenleistung zu erwarten. Bitte beachten Sie, dass für eine übermittelte Zahlung keine Quittung ausgestellt werden kann.

Über den Autor

Christian Bartl

Christian Bartl Projektmanagement & Konzeption für Online und Mobile

Als Technologie-Enthusiast und begeisterter Programmierer entwickle ich in meiner Freizeit Websites, Software und IT-Lösungen, die mir selbst und anderen den Alltag vereinfachen.

mehr auf bartl.me

Kommentare

  1. vhost_anonymized wird so nicht funktionieren. (Tat es zumindest bei mir nicht.)

    Der regexp im Skript erwartet die IP an erster Stelle.

    Also entweder das LogFormat anpassen ("%v:%p " streichen), oder im (ersten else-) regexp das ^ entfernen.

    Den User-Agent hatte ich auch aus dem LogFormat rausgenommen, ob es da noch Probleme gibt, weiß ich daher nicht.

    kommentieren

    1. Hallo j,

      herzlichen Dank für den Hinweis, damit hast du natürlich völlig recht und ich habe das angegebene Logformat im Artikel entsprechend angepasst.

      lg Christian

      kommentieren

  2. ErrorLog hat bei mir nicht funktioniert. Apache2 loggt by default auch den Port und damit funktioniert die regex nicht mehr.

    Ich musste erst
    $Line =~ s/^(.*?\[client \d+\.\d+)\.\d+\.\d+(\].*)/$1.0.0$2/;

    in
    $Line =~ s/^(.*?\[client \d+\.\d+)\.\d+\.\d+\:\d+(\].*)/$1.0.0$2/;
    ändern.

    Das \:\d+ für den Port fehlt.

    kommentieren

Kommentar schreiben

Der hier angegebene Name wird gemeinsam mit deinem Kommentar auf der Website veröffentlicht.

Deine E-Mail-Adresse wird zur einmaligen Benachrichtigung bei Veröffentlichung des Kommentars genutzt.

Benachrichtigung per E-Mail über Antworten auf meinen Kommentar erhalten.

Bitte tippe die Zahlenkombination "3950" ein, nur dann kann ich deinen Kommentar entgegennehmen.

Bitte fülle dieses Feld nicht aus, nur dann kann ich deinen Kommentar entgegennehmen.