Artikel mit ‘d’oh’ getagged

Ach so, na dann.

Montag, 03. August 2009

Wenn wir gegen das Grundgesetz verstossen, weil wir Pädophilen unmöglich machen kinderpornografische Bilder aus dem Internet herunterzuladen, dann nehme ich das in Kauf.

Sagt Thomas Jurk, der Spitzenkandidat der SPD für die Landtagswahl in Sachsen. Gegen Herrn Jurk wurde übrigens schon im letzten Jahr wegen Amtsanmaßung ermittelt, als er, nachdem er von einem Motorradfahrer am Überholen gehindert worden war, jenen kurzerhand mit einer Polizeikelle rausgewunken hat.

Mich persönlich fröstelt es immer ziemlich, wenn einzelne Leute glauben, ihr persönliches Handeln sei in irgendeiner Art und Weise „richtiger“ als das Grundgesetz. Liebe Sachsen, entscheidet weise.

Denial-of-Service mit Gästebuch

Samstag, 29. März 2008

Auf dem Server eines Kunden gab es seit längerem höchst merkwürdige Phänomene: Obwohl die Maschine an sich nur minimal ausgelastet war, hat sie – mit steigender Frequenz – plötzlich Lastspitzen, die die Maschine geradezu unbenutzbar werden ließen. Schnell war ein extrem hoher iowait-Wert identifiziert. Mittels iostat war auch schnell festgestellt, dass der iowait nicht auf eine defekte Festplatte o.ä. zurückzuführen war, sondern zu den Zeiten der Lastspitzen wirklich astronomisch viele Daten auf die Platte geschrieben wurden.

Nun gibt es unter Linux ja einen ganzen Haufen Tools, mit denen man Systemressourcen wie CPU-Zeit oder RAM-Nutzung einschränken oder wenigstens protokollieren lassen kann (Stichworte psacct). Wieviel HDD-Last eine Anwendung erzeugt, kann hingegen meines Wissens nach nicht ausgewertet werden. Sowas könnte ja auch ganz andere Gründe haben, z.B. wenn eine Anwendung unkontrolliert soviel RAM verbraucht, dass die Maschine in den Swap geht. Soll heißen: Die Diagnose eines solchen Problems ist zu einem gewissen Grad einfach Glückssache.

Einigermaßen schnell war geklärt, dass das Problem „irgendwie mit dem Webserver zusammenhängen“ müsse, denn immer, wenn der gestoppt war (was angesichts der Art von Sites und dem mit jenen verbundenen Servicelevel durchaus für einige Minuten tolerierbar war), trat das Problem nicht mehr auf.

Mit Hilfe des server-status-Handlers des Apache schrieb ich einen kleinen Job, der alle paar Sekunden die derzeit abgearbeiteten HTTP-Aufrufe protokollierte. Ziel war, dieses Logfile mit dem Logfile der Lastspitzen abzugleichen, um mit etwas Glück einen Zusammenhang zu einer aufgerufenen Site oder gar einer bestimmten URL herzustellen, um zumindest mal einen Anfang für eine konkretere Analyse zu finden.

Ich gebe gerne zu: Den Aufruf einer Gästebuch-URL habe ich beim Durchsehen des Logfiles unterschwellig ausgeblendet. Ein Gästebuch kann’s ja nun irgendwie nicht sein.

War es aber doch.

Das Gästebuchscript, das sich einer der Kunden installiert (oder vermutlich sogar selbst geschrieben) hatte, speicherte alle Einträge in einer Textdatei, aus der dann schließlich statische HTML-Seiten generiert wurden, durch die man seitenweise blättern konnte. Pferdefuß Nummer 1: Immer wenn vorne ein neuer Eintrag dazu kam, musste hinten der letzte der entsprechenden Seite auf die jeweils folgende Seite rutschen. Das heißt konkret, dass alle HTML-Seiten neu geschrieben werden müssen. Das Problem konkretisiert sich langsam vor dem inneren Auge.

Bisher erschien lediglich die Programmierung ein wenig, ähem, ineffizient. Aber der endgültige Kollaps wurde von der Datenmenge selbst verursacht: Das Gästebuch fasste inzwischen über 16.000 Einträge. Bei 10 Einträgen pro HTML-Seite ergibt das 1600 HTML-Dateien, die im Falle eines neuen Eintrags neu geschrieben werden müssen. Und wenn das noch nicht spannend genug klingt: Die 10 Einträge ergeben mit HTML-Overhead immerhin rund 30 KB. Nun kommen aber, noch ein Pferdefuß, auf jede Seite Links zu den anderen Seiten. Nicht zur davor- und dahinterliegenden, sondern zu allen 1599 anderen Seiten. Mit HTML-Overhead werden daraus rund 120 KB nur für die Links – also rund 150 KB pro HTML-Seite. Multipliziert mit 1600 ergibt das ein Datenvolumen von rund 250 MB, und immer, wenn jemand einen Eintrag hinzufügt, werden diese 250 MB – um einen Eintrag erweitert – auf die Festplatte geknallt.

Das Problem sind nicht die Besucher der Website. Das Problem sind die Spammer. Die bespammen das Gästebuch nämlich durchschnittlich rund 200 Mal pro Tag, mit steigender Tendenz. Das ergibt rund 50 GB Schreibzugriffe pro Tag. Und wir wundern uns über Peaks …

Übrigens: Klickt man auf der betreffenden Website den Link „Gästebuch“ an, kommt man auf eine hübsche Seite, die verkündet: „Das Gästebuch wurde wegen zuviel Spam abgeschaltet“ – die Spammer kannten aber auch ohne Verlinkung von der Website selbst immer noch den ursprünglichen Link, denn vorhanden war das Script nun mal immer noch. Ein besseres Beispiel für den Begriff „Altlast“ habe ich bisher nicht finden können.

Und nochmal übrigens: Solche Analysen gehören bei uns zum üblichen Support, solange sie sich noch „irgendwie im Rahmen“ halten. Der Kunde hat von uns keine Rechnung dafür bekommen.

Nach Hause telefoniert

Donnerstag, 27. März 2008

Gestern bekam ich ein Fax eines Polizeireviers: Ich möge bitte Auskunft darüber erteilen, wer an einem bestimmten Termin Inhaber der IP-Adresse 82.98.82.22 war. Ich war reichlich verwundert, da ich ja nun kein Zugangsprovider bin, sondern meine IP-Adressen alle fest im Rechenzentrum geroutet sind. Auf die einfachsten Varianten (mal die IP im Browser aufrufen, wo dann eine Seite von selfHOST erscheint … oder sich mal das Reverse Lookup anschauen, wo ebenfalls was von selfHOST herauskommt) war man irgendwie noch nicht gekommen.

Einigermaßen verunsichert habe ich zunächst versucht, herauszufinden, worum es denn hier eigentlich geht, denn für meine Kunden lege ich die Hand ins Feuer, und für die Maschine selbst ebenso, da sie von mir gepflegt wird.

Des Rätsels Lösung: Irgendwo in Magdeburg gibt es jemanden, der sich bei selfHOST einen DynDNS-Account zugelegt und auf seinem Rechner eingerichtet hatte. Bei einem Einbruch wurde dieser Rechner nun gestohlen. Nun läuft auf dem Rechner aber ein IP-Updater, der sich bei jeder IP-Änderung bei selfHOST meldet, um dem DynDNS-Dienst die aktuelle IP bekannt zu machen. Die dahinterstehende Logik war also: Wenn nach dem Diebstahl ein IP-Update durchgeführt wird, können wir den Anschlussinhaber der entsprechenden IP ermitteln, denn dort muss dann ja schließlich der entwendete PC stehen.

Lustigerweise hat nun aber eben überhaupt niemand ein IP-Update veranlasst – niemand, außer selfHOST selbst. Dort gibt es nämlich eine automatische Abschaltungsfunktion: Immer, wenn für eine definierte Zeit eben gerade kein IP-Update reinkommt, wird der DynDNS-Account automatisch auf die 82.98.82.22 geschaltet, wo dann eine hübsche selfHOST-eigene Seite darüber informiert, dass der entsprechende per DynDNS angebundene Server wohl gerade offline sei. Das war’s auch schon.

So gesehen muss ich wohl froh sein, dass die Herren in Grün zumindest erstmal freundlich bei mir nachgefragt haben, statt mir direkt eine Hausdurchsuchung anzuhängen. Immerhin bin ich per WHOIS Inhaber des IP-Netzes. Warum die Polizei mich nun eher als Provider und nicht als den endgültigen Inhaber und damit direkt für die IP Verantwortlichen identifiziert hat – wer weiß das schon. Auf jeden Fall: Nochmal gutgegangen! Und das Polizeirevier hat sich anschließend auch nochmal sehr nett für meine Ausführungen bedankt. Bleibt nur zu hoffen, dass der gestohlene Rechner auf anderem Wege wieder auftaucht.

SCRIPT_NAME unter PHP+FastCGI

Mittwoch, 26. März 2008

Auf mehreren Kundenservern setzen wir aus Sicherheitsgründen PHP unter FastCGI in Kombination mit suEXEC ein, in Anlehnung an diese Doku. Das läuft auch weitestgehend unproblematisch, allerdings stehen SCRIPT_NAME und SCRIPT_FILENAME in diesem Fall nicht auf dem Namen des PHP-Scripts, sondern auf dem des PHP-Interpreters, was einige PHP-Scripts etwas durcheinanderbringt.

Für diejenigen, die das für Bug #19656 halten: Nö. Viel simpler ist es mit dem Aktivieren von cgi.fix_pathinfo in der php.ini gemacht.

vorher:

_SERVER["SCRIPT_FILENAME"] = /var/www/virtual/site174/fcgi-bin/php4-fcgi-starter
_SERVER["SCRIPT_NAME"] = /fcgi-bin/php4-fcgi-starter

nachher:

_SERVER["SCRIPT_FILENAME"] = /var/www/virtual/site174/html/shop/info.php
_SERVER["SCRIPT_NAME"] = /shop/info.php


Impressum