toscho.design

PHP: Funktion sanitize_ip

Ich habe mich jetzt entschlossen, neben China auch Südkorea vollständig von dieser Website auszusperren. In den letzten drei Monaten waren 100% aller Zugriffe von dort Hackerversuche. Irgendwann kommt vielleicht einer durch; darauf will ich nicht warten.

Bei ipaddresslocation.org oder proxyserverprivacy.com bekommt man Listen aller IP-Adressen, die zu einem Land gehören. Die muß man jetzt nur in die CIDR-Notation konvertieren; damit die .htaccess einigermaßen übersichtlich bleibt.

Ich habe mir dazu ein kleines Script geschrieben, das ihr gerne benutzen dürft: IP-Adressen nach CIDR konvertieren. Dort stehen ein Beispielcode zum Ansehen und fertige Listen für China und Südkorea zum Download.

Beim Zusammenstecken des Formulares ist mir aufgefallen, daß die Filterfunktionen in PHP zwar ein »sanitize« für alle möglichen Datentypen mitbringen, nicht aber für IPv4.

Ich brauchte eine Funktion, die aus 127.0. ein 127.0.0.0 macht, weil ich manche Blöcke bisher über gekürzte IP-Adressen gesperrt habe.

/**
 * Repariert unvollständige IPv4-Adressen.
 * Usage:
 *      sanitize_ip('127.0');
 * Result:
 *      string(9) "127.0.0.0"
 * @param string $ip
 * @return string
 */
function sanitize_ip($ip)
{
    // Standardverhalten plus Punkt.
    $ip = trim($ip, "\n\r\t\x0B\0. ");

    if ( ! preg_match('~(\d+\.?)*~', $ip) )
    {   // Hat nicht die Form 127.0 oder 127.0.0.
        // Man könnte auch alle falschen Zeichen rauswerfen,
        // aber das wäre zu … weich.
        return FALSE;
    }
    // Mehrfache Punkte entfernen.
    $ip    = preg_replace('~(\.)+~', '.', $ip);
    // In Abschnitte zerlegen.
    $parts = explode('.', $ip);
    // Wieviele haben wir eigentlich?
    $c     = count($parts);
    // Fehlende Abschnitte mit 0 ergänzen.
    for($i = 4 - $c; $i > 0; $parts[] = 0, $i-- );
    // Zusammensetzen und raus damit.
    return implode('.', $parts);
}

Das kann man sicher noch verfeinern. Vorschläge nehme ich gerne entgegen.

12 Kommentare

  1. Jared am 16.09.2009 · 22:58

    Gibt es keine bessere Lösung als eine riesige .htaccess zu haben in der dann hunderte IP Adressen aus China und Südkorea geblockt werden?

    Kann man in einer .htaccess auf andere Dateien verweisen? So das ich nur noch einen kleinen Eintrag dazwischenschieben kann und schon ist ganz Nordkorea geblockt?

    Und ist es überhaupt performant so eine riesige .htaccess laden zu lassen?

    :-) Viele Frage

  2. Thomas Scholz am 16.09.2009 · 23:40

    @Jared: Um die komplette Liste kommt man leider nicht herum, wenn man ein ganzes Land blocken will. Die beste Lösung hierbei heißt nicht .htaccess, sondern httpd.conf. Die wird nämlich nur beim Start des Servers geladen.
    Die .htaccess hingegen wird bei jedem Zugriff auf die Website neu eingelesen.

    Wer also ordentlich an der Ladezeit schrauben will, der steuert alles über die httpd.conf – und verbietet dort den Einsatz einer .htaccess, damit der Server keine Zeit mit Suchen verplempert.

    Allerdings ist das kein »typisches« Szenario: Die meisten Leute betreiben eben keinen eigenen Webserver und können daher nicht auf die httpd.conf zugreifen.

    Das gilt hier auch für mich: Ein eigener Server wäre für diese Seiten derzeit eine lächerliche Geldverschwendung. Meine .htaccess wiegt derzeit 66,1 KiB und bremst nicht meßbar. Ein schlampiger Regex kostet sicher mehr Zeit als 100 Zeilen IP-Adressen.

    Wichtig: Die deny/allow-Regeln müssen vor allem anderen stehen, damit der Server keine Arbeitszeit an jemanden vergeudet, der abgewiesen wird.

    Bei allem Gefrickel gilt letztlich immer nur die harte Empirie: Wie was wirkt, das muß man testen. Die Ergebnisse einer Website kannst du nicht ungeprüft auf eine andere übertragen. Deshalb finde ich es wichtig, mehrere Wege zu kennen.

  3. Jared am 16.09.2009 · 23:44

    Da hast du wohl recht. Wer weiß ob meine Seiten überhaupt von Chinesen attackiert werden...

  4. Thomas Scholz am 16.09.2009 · 23:51

    @Jared: Werden sie. Probier es aus. ☻

  5. David am 18.09.2009 · 22:04

    Ich habe deine 404-Alarm-Mail Methode jetzt auf insgesamt 3 Seiten im Einsatz, Angriffe habe ich noch nicht gemeldet bekommen. Aber vieleicht liegt das ja an den Besucherzahlen, wie stark eine Website solchen Angriffen ausgesetzt ist.

  6. Thomas Scholz am 18.09.2009 · 22:32

    @David: Seltsam. ich habe nur eine Seite, die fast nie attackiert wird, aber die ist auch sehr unbekannt.

    Man müßte mal die Gemeinsamkeiten und Unterschiede betrachten, um vielleicht herauszufinden, wie die Angreifer überhaupt auf die URLs kommen.

    Diese Seiten hier haben viele Backlinks von englischsprachigen Websites und werden von allen, die ich betreue, am meisten angegriffen. Es könnte aber auch einen anderen Grund haben; da bin ich noch unschlüssig.

    Ein direkter Zusammenhang mit den Zugriffszahlen scheint nicht zu bestehen: Ich habe hier gerade mal 4000 Requests am Tag, und rund 600 Requests pro Monat würde ich als »feindlich« bezeichnen. Andere Seiten mit deutlich mehr Zugriffen haben weniger Angriffe.

  7. David am 21.09.2009 · 08:41

    Wenn man vom Teufel spricht… gestern hatte ich zwei Requests aus Südkorea, die mir eine txt Datei mit PHP-Code, die auf einem Russischen Server liegt, einschleusen wollten. Blockst du solche IPs sofort, oder wartest du, ob die wieder kommen?

  8. Thomas Scholz am 21.09.2009 · 10:13

    @David: Die blocke ich sofort. Warum sollte ich denen eine zweite Chance geben?

  9. David am 22.09.2009 · 00:08

    Ich tu mich immer noch schwer mit der eineindeutigen Zuordnung IP-Adresse User. Ich würde gern der IP-Adresse eine zweite Chance geben.

  10. Andy am 29.09.2009 · 13:53

    Jared hat denke ich genau die richtigen Fragen gestellt, aber ob es auch die richtigen Antworten gibt ist fraglich ;-)

  11. GwenDragon am 30.09.2009 · 18:10

    @Andy:

    Jared hat denke ich genau die richtigen Fragen gestellt, aber ob es auch die richtigen Antworten gibt ist fraglich

    Er soll halt mal in seine Logfiles schauen, da wird er schon sehen was aus dem asiatischen Raum so angreift.
    Kommt halt nur drauf an wie veraltet sein Server ist oder wie löchrig FTP-, SSH- oder Mailserver.

  12. Anonymous am 31.10.2009 · 03:44

    Die bessere Variante ist, die Adressen per Firewall zu blocken und nicht über eine htaccess Datei, die ja nur den Webserver steuert. Allerdings ist das Abstellen auf IP-Adressen generell nur eine trügerische Sicherheit und schützt -wenn überhaupt- allenfalls vor irgendwelchen Script-Kiddies.