Vampire - Erweiterung von mod_python, mit dem es etwas Entwicklerfreundlicher wird. Zum Beispiel kann es dann auch automatischen Code-Reload.
apache
Overview of new features in Apache 2.2 - Apache HTTP Server - was alles so neues in Apache 2.2 kommt. Sehr interessant: der Event-MPM. Damit meldet Apache bei Keep-Alive-Sessions endlich wieder zurück an der Spitze (bisher muss Apache pro Keep-Alive einen Worker reservieren, was Apache für Streaming bei grösserer Client-Zahl nahezu unbrauchbar macht).
Django, Apache und FCGI
In Django, lighttpd und FCGI, zweiter Versuch habe ich eine Methode beschrieben, wie man Django mit FCGI hinter einer lighttpd-Installation ausführen kann. Ich habe die Django-FCGIs als eigenständige Server ausgeführt, sodass Sie sie unter unterschiedlichen Benutzern als der Webserver ausführen können. Dieses Dokument gibt Ihnen die benötigten Informationen, um dasselbe mit Apache 1.3 zu tun.
Aktualisierung: Ich pflege meine Beschreibungen jetzt in meinem Trac-System. Siehe die Apache+FCGI-Beschreibung für Django.
Aktualisierung: Ich habe von der Verwendung von Unix-Sockets zur Verwendung von TCP-Sockets in der Beschreibung gewechselt. Der Grund ist, dass Unix-Sockets Schreibzugriff von beiden Prozessen - Webserver und FCGI-Server - benötigen und das manchmal schwer einzurichten ist. TCP-Sockets sind nur ein bisschen langsamer, aber viel einfacher einzurichten.
Zuerst die Hauptfrage, die einige stellen könnten: Warum Apache 1.3? Die Antwort ist einfach: Viele Menschen haben immer noch Apache 1.3 als ihren Hauptserver laufen und können nicht leicht auf Apache 2.0 aktualisieren - zum Beispiel, wenn sie große Codebasen in mod_perl oder mod_python ausführen, werden sie Probleme bei der Migration haben, weil Apache 2.0 mod_perl2 oder mod_python2 erfordert und beide nicht vollständig kompatibel mit älteren Versionen sind. Und obwohl lighttpd ein fantastischer Webserver ist, wenn Sie bereits Apache 1.3 ausführen, gibt es möglicherweise einfach keinen Bedarf für einen weiteren Webserver.
Was benötigen Sie also - neben den Python- und Django-Dingen - für Apache 1.3 mit FastCGI? Nur das mod_rewrite-Modul und das mod_fastcgi-Modul installiert, das ist alles. Beide sollten mit der Verteilung Ihres Systems geliefert werden. Sie werden immer noch alle Python-Dinge benötigen, die ich im lighttpd-Artikel aufgeführt habe.
mod_fastcgi ist etwas eigenwillig in seiner Installation, ich musste ein bisschen damit herumspielen. Es gibt ein paar Stolpersteine, an die ich denken kann:
- Die Angabe des Sockets kann kein absoluter Pfad sein, sondern muss ein relativer Pfad in Bezug auf das FastCgiIpcDir sein.
- Die Angabe des FCGI selbst (auch wenn es rein virtuell ist) muss in einer vollständig qualifizierten Form in Bezug auf das Dokumentenstammverzeichnis, das Sie verwenden möchten. Wenn Sie einen relativen Pfad verwenden, wird er relativ zum Dokumentenstammverzeichnis des Standard-Virtual-Hosts sein - und das ist mit Sicherheit nicht das Dokumentenstammverzeichnis, das Sie verwenden werden, wenn Sie einen Virtual-Host mit dem FCGI einrichten möchten.
- Das FCGI selbst kann nicht innerhalb eines Virtual-Hosts definiert werden - es muss in der Hauptserverkonfiguration definiert werden. Hier kommt das Problem der relativen Adressierung ins Spiel.
- Die Socket-Datei muss sowohl vom FCGI-Benutzer als auch vom Apache-Benutzer lesbar und beschreibbar sein. Normalerweise tun Sie dies, indem Sie die Socket-Datei gruppenschreibbar ändern und die Gruppe dieser Socket-Datei in eine Gruppe ändern, der sowohl der Benutzer als auch der Apache angehören.
Hier ist der Konfigurationsausschnitt, den Sie zu Ihrer httpd.conf hinzufügen müssen. Ich verwende die gleichen Verzeichnisse wie im lighttpd-Beispiel, Sie werden dies wahrscheinlich an Ihre Situation anpassen müssen.
FastCgiExternalServer /home/gb/work/myproject/publichtml/admin.fcgi -host 127.0.0.1:8000
FastCgiExternalServer /home/gb/work/myproject/publichtml/main.fcgi -host 127.0.0.1:8001
<VirtualHost *>
ServerAdmin gb@bofh.ms
Servername www.example.com
ErrorLog /home/gb/work/myproject/logs/django-error.log
CustomLog /home/gb/work/myproject/logs/django-access.log combined
DocumentRoot /home/gb/work/myproject/public_html
RewriteEngine On
RewriteRule ^(/admin/.)$ /admin.fcgi$1 [L]
RewriteRule ^(/main/.)$ /main.fcgi$1 [L]
</VirtualHost> ```
Sie müssen dem Webserver Schreibzugriff auf das Log-Verzeichnis ermöglichen, daher möchten Sie möglicherweise einen anderen Ort dafür verwenden - möglicherweise in `/var/log/apache/` oder wo auch immer Ihr Apache seine Logs hinstellt. Die FastCgiExternalServer-Direktiven müssen außerhalb der Virtual-Host-Definitionen stehen, müssen aber auf Dateien innerhalb des Dokumentenstammverzeichnisses der Virtual Hosts verweisen. Diese Dateien müssen jedoch (und sollten wahrscheinlich nicht) im Dateisystem existieren, sie sind rein virtuell. Die gegebene Einrichtung spiegelt die Einrichtung wider, die ich für das lighttpd-Szenario vorgenommen habe.
Starten Sie nun Ihren Apache neu, starten Sie Ihr django-fcgi.py und Sie sollten auf Ihre Django-Anwendung zugreifen können. Vergessen Sie nicht, die admin_media-Dateien in das Dokumentenstammverzeichnis zu kopieren, sonst wird Ihr Admin sehr hässlich aussehen.
django-fcgi.py --settings=myproject.settings.main --host=127.0.0.1 --port=8000 --daemon django-fcgi.py --settings=myproject.settings.admin --host=127.0.0.1 --port=8001 --daemon
Viel Spaß.
Apache modauthtkt ist ein Framework für Single-Signon in Apache-basierten Lösungen über Technikgrenzen (CGI, mod_perl und was sonst noch so existiert) hinweg. Müsste ich mir mal angucken, könnte für mich interessant sein.
Erste Django Tutorials online
Die Django-Programmierer legen mit den Tutorials los. Das erste Tutorial beschäftigt sich primär mit der Erstellung des Datenbankmodells und des Grundcodes für die zu verwaltenden Objekte und das zweite Tutorial beschäftigt sich mit der automatisch generierten Administrationsoberfläche. Sehr nett, das ganze.
Das System ist natürlich stark auf Content-Erstellung und Verwaltung ausgerichtet - aber trotzdem allgemein genug, so das man es auch für anders gelagerte Inhalte nutzen kann. Die ganze Administration wird automatisch aus dem Objektmodell und einigen Hints erstellt, orientiert sich also immer an den realen Daten im System. Und die Default-Optik ist auch recht ansprechend.
Die Serverintegration geschieht einfach über mod python - also über den Apache. Was ebenfalls ein Vorteil ist, denn mod python bietet sehr hohe Performance schon von Hause aus. Und für heftigere Fälle gibts ja das Caching in Django. Ich muss sagen, was ich bisher von Django sehe gefällt mir ausgesprochen gut.
Ein wichtiger Hinweis fehlt in der Installationsanleitung: Apache2 ist zwingend nötig, und daher auch ModPython in der entsprechenden Version. Mac OS X liefert aber nur Apache 1.3 und viele andere Server haben auch nur den 1.3er Apache zur Verfügung, da hat Django also noch ein echtes Manko.
Wer übrigens auf Debian von Apache zu Apache2 upgraden will: wenn mod perl im Einsatz ist, vergesst es. Das mod perl2 für den Apache2 in der Debian Sarge ist kompletter Schrott - als ob die API-Änderungen in mod perl2 im Vergleich zum alten mod perl nicht schon nervig genug wären. Im Prinzip kriegt man damit keine Perl-Module mehr so einfach zum Laufen.
Update: Übrigens ist gerade im Subversion zu Django eine Menge Aktivität drin um die Pflicht für Apache zu beseitigen. Ein einfacher Entwicklungsserver ist schon drin, man wird also in Zukunft für erste Spielereien keinen Apache mehr benötigen. Und auch das Deployment könnte man damit auf Dauer auch auf andere Beine stellen - z.B. FCGI hinter lighttpd.
Update 2: Das dritte Tutorial ist da und beschäftigt sich mit der Sicht für den Besucher. Die haben ein ganz schön heftiges Tempo im Moment bei Django.
Spyce ist ein Webframework in Python mit verdammt guter Performance: eine einfache Seite mit einem Template hinterlegt bringt auf meiner Kiste über 90 Hits pro Sekunde (Spyce über mod_python in den Apache integriert, Memory-Cache). Take that, PHP!
Apache2, php5-fcgi, php4-fcgi, mod_fastcgi HowTo
Apache2, php5-fcgi, php4-fcgi, mod_fastcgi HowTo liefert alles was man wissen muss um PHP als FCGI-Prozess laufen zu lassen. Und sogar in Deutsch. Das bischen Apache2 da drin kann man selber auf Apache 1.3 umdenken, der Apache ist eigentlich kaum betroffen.
FCGI bietet über Kombination mit suexec die Möglichkeit um PHP pro virtuellem Host unter einem dedizierten User laufen zu lassen und damit die Möglichkeit in shared hosting Umgebungen Files in einem virtuellen Host so anzulegen das ein anderer User mit seinem PHP diese nicht auslesen kann. Man könnte sogar die FCGI-PHPs in einem chroot Jail laufen lassen, um sie noch stärker abzuschotten.
Ausserdem ist FCGI für PHP oft deutlich resourcenschonender, da weniger PHP-Prozesse als Apache-Prozesse laufen können und die Apache-Prozesse nicht so aufgeblasen werden. Wenn man natürlich viele virtuelle Hosts hat, kann das dazu führen das die FCGI-Prozesse wieder an Anzahl gleichziehen - aber dann sollte man sowieso überlegen ob die FCGI-Prozesse nicht besser auf einer dedizierten Maschine laufen sollten.
Für simon wär das genau das richtige, zumal ich dann den anderen Usern auch PHP erlauben könnte.
mod_fastcgi und mod_rewrite
Tja, da hab ich das doch glatt mal ausprobiert mit dem PHP als FastCGI - unter anderem weil ich dann auch gleich ein neueres PHP benutzen könnte. Und was ist? Nix ist. Und zwar gab es ein massives Problem mit mod rewrite Regeln. In der .htaccess vom WordPress wird nämlich alles auf die index.php umgeschrieben. Dazu wird der eigentliche Pfad der angesprochen wurde als PATH INFO an die index.php angehängt. Tja, und das PHP flöht dann diese Informationen da wieder raus und macht das richtige.
Aber als ich FastCGI aktiviert hatte, klappte das nicht - das PHP behauptete immer, das kein Input-File übergeben wurde. Also als hätte ich das PHP ohne Parameter aufgerufen. Die WordPress Administration - die mit normalen PHP Files arbeitet - funktionierte wunderbar. Und auch die Rechtegeschichte klappte gut, alles lief unter meinem eigenen User.
Nur die Rewrite-Rules halt nicht - und damit die ganze Site nicht. Ziemlich blöd, das ganze. Vor allem weil ich das nicht vernünftig testen kann ohne meine Hauptsite runterzureissen. Blöd ist auch, das scheinbar suexec die eigentlichen FCGI-Starter in der Document-Root des primären virtuellen Servers sucht - nicht in denen der eigentlichen Virtuellen Server. Macht die ganze Situation etwas unübersichtlich, da die Programme (die Starter sind ja kleine Shellscripte) nicht da liegen, wo die Dateien liegen. Ausser man hat seine virtuellen Server unterhalb des primären virtuellen Servers angelegt - aber das halte ich persönlich für hochgradig schwachsinnig, da man dann unter Umständen durch direkte Pfadangaben über den Default-Server an im virtuellen Server geladenen Perl-Modulen vorbeikommen kann.
Ergo: ein Reinfall. Leider. Ärgerlich. Jetzt muss ich mir irgendwie erstmal eine Testkiste zusammenstellen mit der ich dieses Problem analysieren kann ...
Update: ein bischen Suchen und Wühlen im Netz und ein kurzer Test und ich bin schlauer: PATH_INFO bei PHP als FCGI-Version unter Apache ist kaputt. Scheinbar kriegt PHP den falschen PATH INFO Eintrag geliefert und den falschen SCRIPT NAME. Dadurch findet der Interpreter bei gesetztem PATH INFO einfach schlicht sein Script nicht und nix geht mehr. Jetzt muss ich also weiter suchen, ob es eine Lösung gibt. cgi.fix pathinfo = 1 (was allgemein als Hilfe dafür geboten wird) funktioniert jedenfalls nicht. Aber wenn ich das richtig sehe gibts keine brauchbare Lösung dafür - jedenfalls keine für mich offensichtliche. Mist.
Update 2: Ich hab eine Lösung gefunden. Diese basiert darauf einfach nicht den Apache zu benutzen, sondern den lighttpd - und den Apache nur als transparenten Proxy vorne vor zu stellen. Das geht ganz gut, vor allem wenn ich den Apache stark entkerne und das PHP dort rauswerfe wird er auch deutlich schlanker. Und lighttpd kann unter verschiedenen User-Accounts laufen, dadurch spare ich mir auch das wilde gehacke mit suexec. Allerdings läuft dann pro User ein lighttpd Prozess (lighttpd braucht nur einen Prozess pro Server, da es mit asynchroner Kommunikation arbeitet) und die PHPs toben sich als FastCGI Prozesse aus, nicht als Apache-integrierte Module. Apache selber ist dann nur für rein statische Präsenzen oder Sites mit Perlmodulen zuständig - davon habe ich nämlich noch eine ganze Reihe. Im Moment habe ich da nur eine Spiel-Site laufen, aber vielleicht wird das in den nächsten Tagen umgestellt. Die Methode wie cruft-free URIs produziert werden ist übrigens recht witzig: bei WordPress kann man einfach das index.php als Error-Document eintragen: ErrorDocument 404 /index.php?error=404 wäre der Eintrag in der .htaccess, bei lighttpd gibt es eine äquivalente Eintragung. Dadurch werden automatisch nicht existierende Files (und die cruft-free URIs existieren ja nicht als physikalische Files) auf WordPress umgeleitet. Dort wird dann geguckt ob wirklich keine Daten da sind für die URI und wenn doch was da ist (weil es eine WordPress URI ist), wird einfach der Status zurückgesetzt. Für letzteres musste ich einen kleinen Patch in WordPress einbauen. Dadurch spart man sich die ganzen RewriteRules und kommt mit fast jedem Server zurecht. Und weil jetzt 1:41 ist, geh ich jetzt mal pennen ...
Alternative Rewrite Rules ergeben eine wesentlich einfachere .htaccess, vor allem eine die nicht ständig von WordPress aktualisiert werden muss. Gerade wenn man selber die .htaccess für andere Sachen noch mitbenutzt ist das praktisch. Ausserdem wird der Apache durch die komplizierten Rewrite-Rules von WordPress auch nicht unbedingt schneller. Ich hab die bei mir mal aktiviert, mal schauen wie sich WordPress 1.5 mit diesen Eintragungen macht. Wenns keine Probleme gibt, bleiben die so drin, denn sie gefallen mir wesentlich besser als die andere Variante. Und sie haben nicht die Probleme die die anderen haben - alte mod_rewrite können nur greedy matching, was die Erstellung von komplizierten Listen von Rewrites ziemlich haarig macht ...
Und nochmal Logfiles
Da ich ja nun ein interessantes Studienobjekt hatte, wollte ich mal gucken inwieweit ich mit ein bischen Clusteranalyse in meinen Logfiles irgendwas interessantes zutagefördern würde. Ich habe also eine Matrix angelegt aus Referrern und zugreifenden IP-Adressen und mir damit mal einen Überblick über typische Userszenarien gemacht - also wie sehen normale User aus im Log, und wie sehen Referrer-Spammer aus und wie sieht unser Freund aus.
Alle drei Varianten lassen sich gut unterscheiden, auch wenn ich im Moment da noch eher davor zurückschrecken würde das algorithmisch zu fassen - das lässt sich nämlich alles recht gut simulieren. Trotzdem sind ein paar Auffälligkeiten zu sehen. Zuerst mal ein ganz normaler Benutzer:
aa.bb.cc.dd: 7 Zugriffe, 2005-02-05 03:01:45.00 - 2005-02-04 16:18:09.00
0065*-
0001*http://www.tagesschau.de/aktuell/meldungen/0,1185,OID4031994 ...
0001*http://www.tagesschau.de/aktuell/meldungen/0,1185,OID4031612 ...
0001*http://mudbomb.com/archives/2005/02/02/wysiwyg-plugin-for-wo ...
0001*http://www.heise.de/newsticker/meldung/55992
0001*http://log.netbib.de/archives/2005/02/04/nzz-online-archiv-n ...
0001*http://www.heise.de/newsticker/meldung/56000
0001*http://a.wholelottanothing.org/2005/02/no_one_can_have.html
Man sieht schön wie dieser User von meinem Weblog weggeklickt hat und wieder zurückgekommen ist - die Referrer sind nämlich mitnichten alles Links auf mich, sondern falsche Referrer die die Browser schicken, wenn der Benutzer von einer Site auf eine andere wechselt. Eigentlich sollen Referrer ja nur dann geschickt werden, wenn auch wirklich ein Link geklickt wird - kaum ein Browser macht das aber richtig. Der Besuch war an einem definierten Tag und er ist direkt eingestiegen durch Eingabe des Domainnamens (die "-" Referrer stehen oben und oben steht der früheste Referrer der vorkommt).
Oder hier mal ein Zugriff von mir:
aa.bb.cc.dd: 6 Zugriffe, 2005-02-04 01:11:56.00 - 2005-02-03 08:27:09.00
0045*-
0001*http://www.aylwardfamily.com/content/tbping.asp
0001*http://temboz.rfc1437.de/view
0001*http://web.morons.org/article.jsp?sectionid=1&id=5947
0001*http://www.tagesschau.de/aktuell/meldungen/0,1185,OID4029220 ...
0001*http://sport.ard.de/sp/fussball/news200502/03/bvb_verpfaende ...
0001*http://www.cadenhead.org/workbench/entry/2005/02/03.html
Ich erkenne mich daran, das Referrer mit temboz.rfc1437.de vorkommen - das ist mein Online-Aggregator. Sieht ähnlich aus - ne Menge falsch geschickter Referrer. Noch ein anderer User:
aa.bb.cc.dd: 19 Zugriffe, 2005-02-12 14:45:35.00 - 2005-01-31 14:17:07.00
0015*http://www.muensterland.org/system/weblogUpdates.py
0002*-
0001*http://www.google.com/search?q=cocoa+openmcl&ie=UTF-8&oe=UTF ...
0001*http://blog.schockwellenreiter.de/8136
0001*http://www.google.com/search?q=%22Rainer+Joswig%22&ie=UTF-8& ...
0001*http://www.google.com/search?q=IDEKit&hl=de&lr=&c2coff=1&sta ...
Dieser kam öfter (also mehrere Tage) über meine Update-Seite auf muensterland.org und zusätzlich hat er noch nach Lisp-Themen gesucht. Und vom Herrn der Schockwelle ist er auch mal gekommen. Absolut typisches Verhalten.
Jetzt mal im Vergleich ein typischer Referrer-Spammer:
aa.bb.cc.dd 6 Zugriffe, 2005-02-12 17:27:27.00 - 2005-02-02 09:25:22.00
0002*http://tramadol.freakycheats.com/
0001*http://diet-pills.ronnieazza.com/
0001*http://phentermine.psxtreme.com/
0001*http://free-online-poker.yelucie.com/
0001*http://poker-games.psxtreme.com/
Alle Referrer sind direkte Domain-Referrer. Keine "-" Referrer - also keine Zugriffe ohne Referrer. Keine sonstigen Zugriffe - würde ich es genauer analysieren nach Seitentyp, würde auffallen das keine Bilder etc. zugegriffen werden. Leicht zu erkennen - sieht einfach mager aus. Typisch ist auch das jede URL nur einmal oder zweimal angegeben ist.
Jetzt unser neuer Freund:
aa.bb.cc.dd: 100 Zugriffe, 2005-02-13 15:06:16.00 - 2005-02-11 07:07:55.00
0039*-
0030*http://irish.typepad.com
0015*http://www208.pair.com
0015*http://blogs.salon.com
0015*http://hfilesreviewer.f2o.org
0015*http://betas.intercom.net
0005*http://vowe.net
0005*http://spleenville.com
Was auffällt sind die Referrer ohne abschliessenden / - untypisch für Referrer-Spam. Ausserdem halt ganz normale Sites. Was auch auffällt, es werden Seiten zugegriffen ohne Referrer - dahinter verstecken sich die RSS-Feeds. Auch dieser ist also leicht von Usern zu unterscheiden. Vor allem da ein gewisser Rhythmus drin ist - scheinbar immer 15 Zugriffe mit einem Referrer, dann den Referrer wechseln. Entweder ist die Referrer-Liste recht klein, oder ich hatte Glück das er zweimal den gleichen bei mir probiert hat - einer ist nämlich 30x da.
Normale Bots braucht man nicht gross zu vergleichen - die wenigsten schicken Referrer mit und sind deshalb völlig uninteressant. Ich hatte einen, der mir aufgefallen war:
aa.bb.cc.dd: 5 Zugriffe, 2005-02-13 15:21:26.00 - 2005-01-31 01:01:07.00
2612*-
0003*http://www.everyfeed.com/admin/new_site_validation.php?site= ...
0002*http://www.everyfeed.com/admin/new_site_validation.php?site= ...
Eine neue Suchmaschine für Feeds die ich noch nicht kannte. Scheinbar hat der Admin gerade vorher irgendwo meine Adresse eingetragen und dann hat der Bot losgelegt die Seiten zu sammeln. Danach hat er dann im Administrationsinterface meine von ihm neu gefundenen Feeds freigeschaltet. Scheint ein kleines System zu sein - der Bot läuft von der gleichen IP wie das Administrationsinterface. Die meisten anderen Bots kommen von ganzen Botfarmen, Webspidern ist halt eine aufwändige Sache ...
Zusammenfassend lässt sich also feststellen, das die derzeitige Generation von Referrer-Spammer-Bots und anderen Mal-Bots noch recht primitiv aufgebaut ist. Sie benutzen keine Botnetze um viele unterschiedliche Adressen zu verwenden und sich dadurch zu verstecken, sie benutzen reine Server-URLs statt Seiten-URLs und haben auch sonst recht viele typische Kennzeichen wie z.B. bestimmte Rhythmen. Ausserdem kommen sie fast immer mehrfach.
Leider sind das keine guten Merkmale um sie algorithmisch zu fassen - ausser man lässt seine Referrer in eine SQL-Datenbank laufen und prüft jeden Referrer mit entsprechenden Selects auf die typischen Kriterien. Darüber könnte man dann durchaus die üblichen Verdächtigen erwischen und gleich auf dem Server blocken. Denn normale User-Zugriffe sehen deutlich anders aus.
Allerdings sind auch schon neue Generationen in der Mache - wie mein kleiner Freund, der mit dem fehlenden /, zeigt. Und dank der dämlichen Browser mit ihren falsch erzeugten Referrern (die viel mehr über die History des Browsers aussagen als über tatsächliche Link-Verfolgung) kann man nicht einfach die referenzierten Seiten gegenchecken, da viele Referrer reine Blindreferrer sind.
ModSecurity - Web Intrusion Detection And Prevention / mod_security ist ein Apache-Modul das in Requests reinguckt und aufgrund von Filtern entscheidet ob ein Request durchgeht oder eine Filtermassnahme (Script, Log etc.) gestartet werden soll. Ganz interessant, auch wenn ich Regelbasiertes Filtern gegen Attacken generell eher skeptisch gegenüber stehe - die finden eben nur bekannte oder erwartete Angriffe. Das gefährliche sind da aber die unerwarteten Angriffe ...
CVS Module for Apache - Ein Apache-Modul welches Dateien aus einem CVS-Repository ausliefert und bei Bedarf einen checkout macht