Das Putzlowitsch Test- und SEO-Blog

IP-Adresse anonymisieren – warum MD5 nicht geeignet ist

Grundlagen zu IP-Adressen und Datenschutz überspringen

Die IP-Adresse

Damit das Internet überhaupt funktioniert, bekommt jeder Teilnehmer eine weltweit eindeutige Adresse zugeordnet. Derzeit ist das nach IPv4 eine 32-Bit Zahl, somit gibt es etwa 4,3 Milliarden mögliche Adressen im Internet. Diese 32-Bit werden üblicherweise in Gruppen zu 8 Bit (Oktett) aufgeteilt und die sich daraus ergebenden 4 Oktette mit einem Punkt getrennt als Zahlen von 0 bis 255 notiert.

Über die IP-Adresse 81.169.145.149 ist z.B meine Schnurpsel-Seite auf einem Web-Server bei Strato erreichbar. Wenn nun jemand meine Webseite aufruft, wird dem Webserver auch die IP-Adresse des Aufrufers mitgeteilt. Klar, der Server muß ja wissen, wo er die angeforderte Webseite als Antwort hinschicken soll.

Nebenbei legt der Webserver aber auch eine sogenannte Logdatei an, in welcher alle Zugriffe protokolliert werden und stellt die IP-Adresse auch dem für die Erstellung der Seite zuständigen Programm zur Verfügung. So speichert WordPress z.B. zu jedem Kommentar auch die IP-Adresse des Kommentators in der Datenbank.

IP-Adressen verwenden

Mit den gespeicherten IP-Adressen kann man so allerlei anstellen. Zum einen sind sie hilfreich, um unerwünschte Zugriffe abzuwehren. Wenn z.B. von einer bestimmten IP-Adresse regelmäßig viel Kommentarspam kommt, kann man den Webserver anweisen, einfach alles zu ignorieren, was von dieser IP-Adresse kommt.

Interessant ist auch die Möglichkeit, mit der IP-Adresse und weiteren Daten eine Statistik zu erstellen. So kann man herausfinden, wieviele Besucher wann welche Seiten aufrufen, woher so kommen und wohin sie gehen. Dazu ist es erforderlich, die Benutzer unterscheiden zu können, unter anderem durch ihre unterschiedlichen IP-Adressen. Wenn jemand mit der IP-Adresse 10.48.80.4 auf meine Seite zugreift, weiß ich zwar nicht, wer das ist, aber ich kann davon ausgehen, daß es jemand anderes war, als der mit der IP-Adresse 10.130.1.247.

Die personenbezogene IP-Adresse

Zwar kann ich nicht wissen, welcher konkrete Benutzer hinter einer IP-Adresse steckt, wohl aber der Internet-Service-Provider (ISP). Wenn ich über meinen Internetzugang per DSL mit dem Internet verbunden bin, bekomme ich eine IP-Adresse von meinem Provider 1&1 zugeteilt. Der Internetanbieter speichert diese Zuordnung technisch bedingt zumindest für die Dauer der Verbindung, schließlich muß auch er wissen, zu welchem Kunden (DSL-Anschluß) er die Daten für die IP-Adresse schicken muß.

Für Abrechnungszwecke wird diese Verknüpfung eines Kunden mit einer IP-Adresse zu einem bestimmten Zeitpunkt möglicherweise auch länger gespeichert. Seit einiger Zeit ist diese Vorratsdatenspeicherung per Gesetz sogar unabhängig davon für mindestens 6 Monate vorgeschrieben.

Somit kann meine IP-Adresse durch den ISP mir als Kunden, und damit einer Person zugeordnet werden. Für sich allein genommen ist die IP-Adresse keine personenbezogenes Datum, sie wird es aber durch die beim Internetanbieter gespeicherten Informationen.

Speicherung personenbezogener Daten

Da der Schutz der Privatsphäre und persönlicher Daten ein hohes Gut ist, darf nicht jeder einfach ohne Einwilligung personenbezogene Daten speichern. Auch hier gibt es entsprechende gesetzliche Regelungen, einerseits im Bundesdatenschutzgesetz und andererseits im Telemediengesetz.

Wenn man nun eine IP-Adresse als personenbezogenes Datum betrachtet und andererseits solche Daten, insbesondere ohne Einwilligung des Betroffenen, nicht gespeichert werden dürfen, ist das Speichern der IP-Adresse, wie es bisher gehandhabt wird, nicht zulässig.

Der einfachts Ausweg ist, die IP-Adresse nicht zu speichern. Solange das im eigenen Einflußbereich liegt, ist das die radikalste und einfachst Lösung. Damit hat man aber keine Möglichkeit mehr, eine IP-Adresse für die Abwehr unerwünschter Zugriff oder edie Webseiten-Statistik zu verwenden.

Die zweite Möglichkeit ist, die IP-Adresse in anonymisierter Form zu speichern. Damit geht die Zuordnung der IP-Adresse zu einer Person verloren, die Unterscheidbarkeit bleibt aber idealerweise weitestgehed erhalten.

Wie anonym ist eine Anonymisierung wirklich?

Ich war ja dem Irrtum auch erlegen, daß man mit einer kryptographischen Hashfunktion wie MD5 eine IP-Adresse anonymisieren kann. Auch wenn MD5 mittlerweile als kryptographisch nicht mehr wirklich sicher gilt, sollte es doch für eine Anonymisierung reichen. Das tut es prinzipiell auch, aber nur dann, wenn die zu anonymisierenden Daten nicht aus einer überschauberen Datenmenge mit bekannter Struktur bestehen.

IP-Adressen haben aber eine wohlbekannte Struktur und auch wenn 4,3 Milliarden Möglichkeiten erstmal nach viel klingt, ist es eine gut überschaubare und handhabbare Größenordnung. Bei mit MD5 „anonamisierten“ IP-Adressen ist es einfach möglich, die zu einem MD5-Wert gehörende Adresse durch probieren herauszufinden. Man bildet einfach von alle IP-Adressen den MD5-Wert und vergleicht ihn mit dem unbekannten Wert. Dann ist es nur eine Frage der Zeit, bis man die passende IP-Adresse gefunden hat.

md5 to ipUm mal ein Gefühl dafür zu bekommen, wie schnell das geht, habe ich eine kleines PHP-Programm geschrieben und hier auf dem Server laufen lassen. Um den Server nicht zu sehr zu belasten und auch das 30 Sekunden-Zeitlimit nicht zu überschreiten, lasse ich das erste Oktette nicht berechnen, beleiben theoretisch gut 16 Millionen Versuche.

Kurz und gut, meine verkürzte IP-Adresse war nach gut 9 Millionen Versuchen und in etwa 13 Sekunden ermittelt. Im ungünstigsten Fall und mit der kompletten IP-Adresse dürfte das etwa 2 Stunden dauern. Wobei PHP als nicht besonders schnell gilt und das zudem auf einem Webserver läuft, den ich mir mit vielen anderen Kunden teile. Damit ist klar, eine mit MD5 anonymisierte IP-Adresse ist nicht anonym, da sie in relativ kurzer Zeit rekonstruiert werden kann.

So eine MD5-IP-Adresse hat noch eine anderen Nachteil, sie sieht nicht mehr wie eine IP-Adresse aus. Statistikprogramme könnten darüber möglicherweise stolpern.

Und nun?

Anonymisierung durch Weglassung

Die einfachst Möglichkeit ist, wenn eine IP-Adresse gespeichert werden soll, diese komplett auf Null zu setzen, also 0.0.0.0. Das ist dann wunderbar anonym, allerdings sind alle IP-Adressen identisch. So wird das nichts mit der Statistik und der Spamabwehr.

Aber vielleicht genügt es ja schon, nur einen Teil der IP-Adresse wegzulassen bzw. mit einem festen Wert zu belegen. Aber was und wieviel kann man weglassen, so daß kein zu großer Fehler entsteht, die Anonymität aber trotzdem gewahrt wird. Meine erste Idee war, das am weitesten links (höchstwertige) Oktett zu anonymisieren, anderenorts habe ich gelesen, daß das am weitesten rechts liegende (niederwertigste) Oktett genommen wird. Um zu sehen, wie sich die verschiedenen Möglichkeiten auswirken, habe ich die nicht anonymisierten Logdaten einer Woche genommen, und die Anzahl der unterschiedlichen IP-Adressen mit der Anzahl nach der Anonymisierung verglichen:

Methode Anzahl Abw. abs Abw. rel
Original 19429 0 0.00%
1. Oktett 19416 13 0.07%
1. und ¼ 2. Oktett 19381 48 0.25%
1. und ½ 2. Oktett 19252 177 0.91%
1. und ¾ 2. Oktett 18712 717 3.69%
1. und 2. Oktett 16819 2610 13.43%
4. Oktett 17080 2349 12.09%

 
Insgesamt gab es in der betrachteten Woche 145636 Zugriffe von 19429 unterschiedlichen IP-Adressen (7.50 Requests/IP). Den nicht anonymisierten Wert findet man in der ersten Zeile, alles bleibt erhalten, Fehler 0%. In der zweiten Zeile habe ich das 1. Oktett mit einer 10 ersetzt. Damit landen die IP-Adressen im Bereich der privaten IP-Adresen, die so in freier Wildbahn nicht anzutreffen sind. In den weiteren Zeilen habe ich zum auf 10 gesetzten ersten Oktett noch jeweils zwei, vier und sechs Bit des zweiten Oktetts auf 0 gesetzt, um den Anonymisierungsgrad zu erhöhen. In der letzten Zeile wurde schließlich nur das 4. Oktett auf Null gesetzt.

Der Fehler ist bis zu „1. und ¼ 2. Oktett“ oder sogar „1. und ½ 2. Oktett“ aus meiner Sicht akzeptabel. Mit so einem Fehler könnte man für statistische Auswertungen gut leben. Bei der Variante mit dem 4. Oktett ist der Fehler schon recht hoch, vor allem deutlich höher als beim „nur 1. Oktett“, obwohl ja die anonymisierte Datenmenge von 8 Bit gleich ist. Der Unterschied ist wohl damit zu erklären, daß meine Webseite nur vorwiegend regionales Publikum hat. So kommen die meisten Besucher aus Deutschland und damit habe diese vorwiegend IP-Adressen aus dem Pool einiger, weniger Internetanbieter. Diese unterscheiden sich dann halt oft nur in der letzten Stelle der IP-Adresse.

Wirklich anonym?

Das eine „Anonymisierung“ mittels MD5 nicht funktioniert ist klar, inwieweit das teilweise Weglassen von Daten der IP-Adresse als Anonymisierung reicht, kann ich nicht beurteilen. Zumindest läßt sich die IP-Adresse nicht mehr unmittelbar zurückrechnen, da die Daten teilweise gelöscht werden. Vielleicht kann sich ja hier jemand dazu äußern, der sich mit sowas auskennt.

5 Kommentare »

Mit Werbung Geld im Internet verdienen, so einfach ist das

Meist sehe ich einen Großteil der Werbung auf Internetseiten nicht, nun habe ich aber mal testweise meine Werbeausblendemaschine ausgeschaltet und war verwundert, wo überall Werbung auftaucht. Teilweise enthalten die Seiten mehr Werbung als Inhalte und die Inhalte sind zudem noch nicht mal eigene.

Geld mit einer Suchmaschine verdienen

Erstes Beispiel ist die „Suchmaschine“ Tixuma. Die Suchergebnisse dort stammen von Yahoo, die Yahoo-API „BOSS“ erlaubt ausdrücklich das Erstellen eigener Suchapplikationen. Das eigentlich interessante ist aber das Geschäftsmodell hinter dieser Seite. In den FAQ steht dort:

1.1. Was ist Tixuma ?
Tixuma ist eine Suchmaschine, die seinen registrierten Usern Geld dafür zahlt, daß diese Tixuma für Ihre Suche im Internet verwenden. Zu diesem Zweck wird, wie bereits von anderen Webseiten bekannt, Werbung in Form von Werbebanner etc., in den Suchergebnissen eingeblendet. Im Gegensatz zu anderen Seiten jedoch, werden bis zu 80% der Werbeeinnahmen an seine User ausgeschüttet.

Auch der Name ist recht gut gewählt, denn wenn man Tixuma in die Laute zerlegt, kommt da z.B. Tick-Suma raus. Na, macht es klick? :-)

Geld mit Twitter verdienen

Zweites Beispiel ist die…, ja was ist das eigentlich? Na egal, das zweite Beispiel ist Twitter-Trends. Dort werden mit der Twitter-API Trends und Tweets abgegriffen und mit Google-Adsense-Werbung umgeben.
Auf der Startseite steht:

Der beliebte Zwitscherdienst Twitter wird heute auf vielseitige Weise genutzt. Um zu erkennen, welche Themen derzeit angesagt sind, wurde diese Seite erschaffen. …

Ich habe eher den Eindruck die Seite wurde geschaffen, um mit Google-AdSense-Werbung Geld zu verdienen :-)

Das Rezept für schnelles Geld im Internet

Man nehme die API eines großen Webdienstes, greife dort die Inhalte ab, zeige sie auf einer eigenen Webseite an und packe ordentlich Werbung drumherum. Fertig ist die Laube.

Gut, ein kleines Detail will ich nicht verschweigen. Man sollte sich zumindest grundlegend mit Programmierung, z.B. in PHP, auskennen, um die API-Funktionen nutzen zu können. Oder man kennt jemanden, der sich damit auskennt. Oder man findet jemanden, der davon Ahnung hat, z.B. über eine Online-Anzeige. :-)

2 Kommentare »

Metaphysik und Müllabfuhr in WordPress 2.9.x

Meta-stase

Durch diese kurze Meldung zu WPMU habe ich erst mitbekommen, daß es in WordPress seit Version 2.9 eine neue Tabelle ‚wp_commentmeta‘ gibt. Für User und Posts gibt es ja schon länger die dazugehörigen Metadaten in wp_usermeta und wp_postmeta. Nun war ich natürlich neugierig, wofür diese neuen Kommentar-Metadaten in WordPress verwendet werden.

Müllabfuhr

MülltonnenEin wichtiger Punkt ist der seit WP 2.9 eingeführte Papierkorb (Trash). Hier werden Artikel, Seiten und auch Kommentare nicht sofort gelöscht, sondern landen zunächst im Papierkorb.

Genau dafür sind diese Metadaten wichtig. Der Trash-Status wird zwar direkt in den Tabellen wp_posts im Feld post_status als ‚trash‘ und wp_comments im Feld comment_approved als ‚trash‘ bzw. ‚post-trashed‘ vermerkt, zusätzlich aber auch in den Metadaten. Neben dem Status wird auch der Zeitpunkt des „Wegwerfens“ in den Mülleimer festgehalten, und dafür gibt es keine Felder in den Post- und Kommentartabellen, dafür werden die Meta-Tabellen auf jeden Fall benötigt. Deshalb gibt es nun eine Tabelle für Comment-Metadaten.

Aber wen interessiert es, wann die Sachen in den Müll gewandert sind? Die WordPress-Müllabfuhr. Die kommt einmal am Tag vorbei und nimmt alles mit, was schon länger als 30 Tage in der Tonne liegt. Man kann ihr aber auch sagen, das sie den Müll schon früher entsorgen soll oder bitte länger liegen läßt. Ein Eintrag in der wp-config.php genügt:

define( 'EMPTY_TRASH_DAYS', 30 );

Die 30 durch die gewünschte Anzahl an Müllvorhaltetage ersetzen.

Metaphorisch

Aber das ist natürlich nicht alles, was man mit den neuen Kommentar-Metadaten machen kann. Genau wie durch die Post-Metadaten bei Artikeln und Seiten ist es nun möglich, nahezu beliebige Daten zu einem Kommentar zu speichern. Der Phantasie sind da kaum Grenzen gesetzt. Denkbar wäre, hier die beliebte Sternchen-Wertung zu einem Kommentar abzuspeichern. Oder ein…, naja, mir fällt im Moment erstmal nichts weiter ein.

Die Funktionen für die Kommentar-Metadaten gibt es genauso wie für Post-Metadaten. Also z.B. update_post_meta -> update_comment_meta, get_post_meta -> get_comment_meta usw. Die Parameter sind praktisch dieselben, außer das dann natürlich nicht die Post-ID, sondern die Comment-ID übergeben wird.

Meta-don

Für Theme- und Pluginentwickler bieten die neuen Comment-Metadaten sicher berauschende Möglichkeiten für ganz neue, tolle und bisher ungeahnte Funktionen mit den WordPress-Kommentaren. :-)

Keine Kommentare »

Was gibt’s Neues? – 123 Tweets

Schnurpsel 123 Tweets
So sieht gerade mein Twitter-Status (Putzlowitsch) aus, also insgesamt habe ich bisher 123 Tweets abgesetzt. Bei „123 Tweets“ sind mir spontan meine WordPress-Plugins eingefallen, die ich auch immer „123 Irgendwas“ nenne. Da müßte ich jetzt also mal ein Twitter-Plugin entwickeln, daß ich dann „123 Tweets“ nennen kann.

Ich weiß zwar noch nicht genau, was das Plugin machen wird, aber eine Idee habe ich schon. Da ich Twitter bisher im wesentlichen als Linkschleuder für meine Blogartikel verwende, könnte ich das doch gleich automatisieren. Wenn ich einen neuen Artikel publiziere, wird wird gleich ein entsprechender Tweet abgesetzt. Na mal sehen…

Ein Kommentar »

Strato PowerPlus mit SpeedPlus – Fehler bei der Remote-Adresse (REMOTE_ADDR)

Nachtrag am 22.01.2010:

Seit heute scheint das weiter unten geschilderte Problem mit der Remote-Adresse nicht mehr zu bestehen. Die Einträge in der .htaccess-Datei oder sonstige Eingriffe sind daher möglicherweise nicht mehr erforderlich.
Bei mir ist das Problem verschwunden, aber offensichtlich noch nicht generell.

Nachtrag am 01.03.2011:

Nach aktuellen Informationen ist das Problem wohl nun doch endgültig behoben worden. Die Einträge in der .htaccess-Datei oder sonstige Eingriffe sind daher nicht mehr erforderlich.

Seit Anfang Dezember 2009 bin ich mit meiner Schnurpsel-Seite wieder zurück zu Strato umgezogen. Ganz weg war ich ja nicht, ich hatte nur den Hostnamen bei einem anderen Anbieter aufgeschaltet. Aber seit es nun SpeedPlus bei Strato gibt, bin ich nun doch wieder zurückgekehrt.

Die Geschwindigkeit ist wirklich gut. Antwortzeiten von ungefähr 0,5 Sekunden gegenüber 3 bis 4 Sekunden vorher sind für ein PHP-Schwergewicht wie WordPress eine merkliche Verbesserung. Zudem wurde auch gleich das ohne-www-Problem beseitigt, in der Umgebungsvariable HTTP_HOST steht nun der tatsächlich im HTTP-Request angegebene host drin.

Die Remote-IP-Adresse (REMOTE_ADDR)

Neben allerlei anderen interessanten Informationen wird bei jedem Webseitenaufruf auch die IP-Adresse des Aufrufers in einer Umgebungsvariablen vermerkt. Auf diese kann z.B. mit Skriptsprachen wie PHP oder Perl als Variable „REMOTE_ADDR“ zugegriffen werden. Diese Remote-Adresse ist z.B. für statistische Auswertungen interessant oder kann beim Aussperren unerwünschter Zugriffe (Spam-Bots) helfen.

Allerdings zählt diese IP-Adresse ja nach Auffassung und Auslegung der Gesetze zu den personenbezogenen Daten und dürften dann eigentlich nicht gespeichert werden. Bei Strato werden die IP-Adressen in den den Kunden zur Verfügung gestellten Serverlogdateien in anonymisierter Form gespeichert. Auch die im Kundenmenü anzeigbare Webseiten-Statistik greift auf diese Daten zurück.
So können die Zugriffe zwar unterschieden aber nicht einem konkreten Anschluß zugeordnet werden

Mehr Geschwindigkeit mit SpeedPlus

Wenn ich die Grafik zu SpeedPlus bei Strato richtig deute, werden die Zugriffe nicht mehr direkt auf die Webserver geroutet, sondern von einem Loadbalancing-Cluster lastabhängig verteilt.
Diese Verteilung funktioniert vermutlich ähnlich wie bei einem nicht-transparenten Proxy, denn für den Webserver sieht es so aus, als würde der Strato-interne Server die Seite anfordern. Genau deshalb steht in der Remoteadresse nicht mehr die IP-Adresse des Aufrufers drin, sondern eine 81.169.145.xxx drin.

Komischerweise tritt der Effekt aber nicht bei allen Domains auf, nur die Hälfte meiner Domains (inkl. Subdomains) bei Strato ist davon betroffen.

Die richtige Remoteadresse ermitteln und setzen

Ich wäre ja nicht Schnurpsel, hätte ich nicht bereits eine Lösung für das Problem parat :-)
Die richtige IP-Adresse findet man im Request-Header-Feld X-Forwarded-For, daß heißt der Strato-Server trägt hier die Adresse ein, von der er die Anforderung erhalten hat.

In Skriptsprachen wie PHP oder Perl steht diese Variable als „HTTP_X_FORWARDED_FOR“ zur Verfügung. Hier könnte man sich die Remote-Adresse also einfach möglichst am Anfang (bei WP z.B. in der wp-config.php) der Abarbeitung in die REMOTE_ADDR eintragen, z.B. so:

if( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
  $ip_addr = @trim( @end( @explode( ",", $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) );
  if( '' != $ip_addr )
    $_SERVER['REMOTE_ADDR'] =  $ip_addr;
}

Hier kommen zwei wichtige Aspekte zum Tragen, denn in „X-Forwarded-For“ können mehrere durch Komma getrennte IP-Adressen stehen, sofern unterwegs mehrere Proxies durchlaufen wurden. Außerdem soll die Adresse nicht überschrieben werden, falls kein X-Forwarded-For-Feld existiert oder aus anderem Grund nicht ermittelt werden kann.

Für Perl könnte das etwa so aussehen:

if( $ENV{'HTTP_X_FORWARDED_FOR'} ne "" )
{
  my @ip_list = split(/,/, $ENV{'HTTP_X_FORWARDED_FOR'});
  $ENV{'REMOTE_ADDR'} = $ip_list[-1]; 
}

Nachteil ist hierbei natürlich, daß man alle Webapplikationen, die irgendwie die REMOTE_ADDR verwenden, entsprechend anpassen muß. Es geht aber auch noch einfacher und allgemeiner.

Umgebungsvariablen mit mod_setenvif setzen

Das Apache-Modul mod_rewrite kennen bestimmt viele WordPress-Nutzer, manch einer kennt vielleicht sogar mod_alias, aber vermutlich nur wenige haben schon mal etwas vom Modul mod_setenvif gehört. Es kommt auch ganz bescheiden und unspektakulär mit nur vier Anweiungen daher.

Mit dem Modul mod_setenvif hat man die Möglichkeit, Umgebungsvariablen abhängig von Request-Feldern zu setzen. Genau das brauchen wir hier. Wir haben das Request-Feld X-Forwarded-For und wollen abhängig davon die Umgebungsvariable REMOTE_ADDR setzen. Das Problem läßt sich mit ein bißchen Regular-Expression in einer Zeile in der .htacces erschlagen:

SetEnvIf X-Forwarded-For "(.+,)? *(.+)$" REMOTE_ADDR=$2

Optimalerweise steht diese Zeile ganz am Anfang einer .htaccess im Wurzelverzeichnis des Webpaketes. Dann wirkt sei auch auf alle Domains oder Subdomains, die ihr sichtbares Wurzelverzeichnis in einem Unterverzeichnis des Webspace haben.

Das schöne an diesem kleinen Eingriff ist, daß er auch auf das Serverlogfile und die Webstatistik wirkt. Im Logfile stehen nun wieder zwar anonymisierte, aber unterscheidbare Zugriffe und die Webstatistik zeigt nicht mehr 10000 Zugriffe von nur 5 Adressen an.

Ende gut, alles gut?

Mit ein bißchen Handarbeit kann man wieder mal einen Strato-Konfigurationsfehler ausbügeln. Andereseits ist die SpeedPlus-Plattform noch recht neu, da können solche Fehler schon mal auftreten. Ich habe das Problem auch bereits vor 10 Tagen an den Strato-Support gemeldet, warte aber immer noch auf die Antwort zu meinem Ticket. Scheint etwas komplizierter zu sein. Bis zur Strato-Problemlösung kann mein kleiner „Trick“ zumindest über die Zeit helfen.

7 Kommentare »