Ad hoc Apache Log Analyse mit Webalizer per Kommandozeile

Webalizer ist neben "awstats" ein Urgestein zur Analyse des Verlaufs von Webseitenzugriffen. Webalizer wertet Webserver-Log-Dateien aus; letztere müssen dafür eines unter mehreren normierten Formaten (z.B. das clf-Format; s. https://en.wikipedia.org/wiki/Common_Log_Format) aufweisen.

Ergebnis der Auswertung sind HTML-Seiten und Grafiken, die man z.B. über einen Webserver abrufen kann. Man installiert das Tool deshalb normalerweise auf einem zentralen Analyse-Webserver. Über periodische cron-Jobs

  • sammelt man sich dann regelmäßig aktuelle Log-Dateien anderer, zu analysierender produktiver Webserver zusammen,
  • transferiert die Logs dann zu der zentralen webalizer-Installation auf dem Analyse-Server,
  • lässt dort die Analyse durchführen
  • und ruft dann nach Bedarf die aufbereiteten Ergebnis-HTMLs auf.

Hört sich kompliziert an. Tatsächlich kann man sich als Anfänger schon mal im Gestrüpp der Konfigurationsoptionen und des Webserver-Setups verheddern. Die meisten Manuals und "docs" konzentrieren sich auf das obige Szenario - und verstellen so leider ein wenig den Blick auf das Wesentliche. In vielen Fällen geht es nämlich auch viel einfacher:

"webalizer" lässt sich auch auf der Kommandozeile einsetzen und ein Webserver ist überhaupt nicht nötig, wenn man mal ad hoc eine Log-Auswertung durchführen möchte oder muss.

Vor kurzem hatte ich einen solchen Fall - und fand das interessant genug, diesen kleinen Blog-Post zu schreiben.

Die Aufgabenstellung

Vor ein paar Tagen wandte sich ein Bekannter aus Norwegen, dessen Webseite plötzlich über fast 48 Stunden nicht mehr erreichbar war, an meine Frau. Als Ursache ergab sich schließlich, dass der dortige Weg-Hosting-Provider, der interessanterweise über einen sekundären Provider in den USA hosten lässt, Parameter zur Begrenzung der Bandbreite der Webserver-Zugriffe gesetzt hatte. (Off Topic: Dieses gestaffelte Hosting (man spricht auch von "Web-Hotels" - ist in Norwegen Gang und Gebe - ohne dass die Kunden erfahen würden, dass ihre Daten in die USA wandern. Aber da der Durchschnittsnorweger nach meiner Erfahrung an Datenschutz kaum interessiert ist, ist das dort auch kein Thema.)

Gedacht war die Bandbreitenbegrenzung nach erhaltener Auskunft wohl als einfache Sicherheitsmaßnahme; akut führte das Überschreiten der relativ geringen Grenzwerte aber zum Ausfall der Website über fast 2 Tage hinweg.

Nun hätte man ja vielleicht erwarten können, dass sich der norwegische Provider auch um die Ursache der offenbar gestiegenen Bandbreitenanforderungen kümmern würde. Auf Anfrage hatte unser Bekannte aber nur die lapidare Auskunft erhalten, es handele sich wohl um einen "normalen Anstieg des Datenverkehrs auf der Webseite". So etwas macht mich immer misstrauisch. Es ist zwar nicht unser Job, die Webseite zu überwachen, aber wir haben uns dann im Auftrag des Bekannten mal die Apache Log-Dateien vom Provider zuschicken lassen.

Ich war gerade unterwegs und hatte nur meinen Laptop dabei, als die Log-Dateien eines ganzen Jahres per Mail eintrafen. Für eine erste Analyse genügten dann tatsächlich ein

  • Internetzugang (inkl. DNS-Server-Zugang),
  • "webalizer" auf der Kommandozeile
  • und ein Browser.

Einen Internetzugang erhielt ich über das Hotel, in dem ich abgestiegen war. Die bescheidenen Voraussetzungen sind natürlich nützlich, wenn man mal aus der Ferne Ursachenforschung betreiben soll und keinen Zugang zum betroffenen Webserver hat.

Webalizer auf der Kommandozeile

Man hat also einen Haufen von Log-Dateien vorliegen und will die auswerten. Wie geht man vor?

  • Schritt 1: Zunächst muss man sich webalizer natürlich aus einem Paket-Repository seiner Linux-Distribution installieren. Dabei treten nach meiner Erfahrung keine Besonderheiten auf.
  • Schritt 2: Um die Arbeit etwas zu organisieren, sollte man sich ein "Log-Verzeichnis" zur Aufbewahrung der Log-Dateien bzw. ein "Zielverzeichnis" für die von webalizer erzeugten Output-Dateien anlegen. Bezeichnen wir die Pfade für unseren Fall mal mit "Path_To_Logs/logs_nw" bzw. "Path_To_Results/webalizer_nw". Für systematische Arbeiten sollten die Verzeichnisse natürlich sprechende Namen bekommen.
  • Schritt 3: Es schadet nie, einen kurzen filternden Blick in die man-Seiten eines neuen Kommandos zu werfen. Wir lassen uns durch die Vielfalt der dortigen Optionen zu webalizer aber nicht verwirren. Die Kommandostruktur ist einfach:
    "webalizer [Optionen] Pfad_zu_einer_Log-Datei".

    Nun zu den Optionen:

    • "-v" für "verbose" ist für das Experimentiern mit Linux-Kommandos immer gut.
    • Ferner erschient es logisch, dass wir die Ergebnisse irgendwie bezeichnen müssen; wir entdecken hierzu die Optionen "-n" und "-t" .
    • Dann ist klar, dass wir mehrere Dateien hintereinander auswerten müssen, ohne die Ergebnisse vorheriger Arbeit verlieren zu wollen. Wir finden hierzu die Option "-p" für "Incremental".
    • Das Output-Verzeichnis muss bekannt gegeben werden; hierzu dient die Option "-o".

    Für alles andere verlassen wir uns im Moment mal optimistisch auf Standardwerte.

  • Schritt 4: Wir bemühen schließlich die Kommandozeile - in meinem Fall mit:

    ich@mytux:~>webalizer -v -p -n norway-domain -t nw-since-2016 -o Path_To_Results/webalizer_nw   Path_To_Logs/logs_nw/NAME_OF_LOG_FILE

"NAME_OF_LOG_FILE" ist oft von der Form "Domain-Bezeichnung_Monat-Jahr.gz" - z.B.: anracom.com-Jan-2016.gz". Ja, gezippte Dateien sind zulässig; webalizer kümmert sich intern selbst um den Aufruf von "gunzip".

Das war's auch schon. Nun kann man auf der Kommandozeile seine vielen Log-Files händisch aufrufen. Oder aber ein kleines Script schreiben, das den Aufruf der verschiedenen Logdateien und die nötige Variation des Zeitanteils im Dateinamen für einen erledigt.

Während der Auswertung (mit der Option "-v") erhält man auf der Standardausgabe (im Terminalfenster) typischerweise viele Meldungen zur Reverse-DNS-Analyse.

Ergebnisdarstellungen

Sieht man in das Zielverzeichnis und auf die dort erzeugten Dateien, so bietet sich einem ausschnittsweise etwa folgendes Bild

Es gibt also viel Grafik-Dateien, weitere Hilfsdateien und eine "index.html"-Datei. Letztere können wir aber im Browser unserer Wahl (meist über einen Menüpunkt "Datei öffnen") direkt aufrufen.

Die Ergebnisse der Auswertungen werden uns danach in Form einfacher Tabellen und Grafiken im Browserfenster präsentiert. In meinem Fall ergab sich etwa folgende Einstiegsseite:

Extrem auffällig ist hier sofort der ungewöhnlich hohe Wert an transferierten Daten - insbesondere im Februar 2017. Schauen wir uns das mal genau an, indem wir auf den Link für Februar klicken; ich zeige nachfolgend nur Ausschnitte aus der detaillierten Seite für selbigen Monat:

Diese Grafik spricht schon mal dafür, dass die Hauptzugriffe nicht aus einer mitteleuropäischen Zeitzone erfolgen. Faktisch zeigen weitere Graphen, die ich hier nicht abbilde, dass viele Besucher in den USA lokalisiert waren.

Es lohnt sich, danach eine Blick auf die vielen anderen Grafiken zu werfen, die einem webalizer zu anderen Zusammenhängen bzgöl. erfasster Zugriffsdaten anbietet. Als ich mir etwa die Zuordnung der Datentransfermenge zu Ursprungsadressen ansah, ergab sich Folgendes:

Aha, da erkennen wir, dass die großen Dateitransfers von einigen wenigen Hosts erzeugt werden. Eine genauere nachfolgende Analyse führt dann etwa über die Ermittlung der zugehörigen IP-Adressen (z.B. mit ping oder gezielten DNS-Abfragen) und ein systematisches Durchsuchen von Blacklists im Internet.

So erhalten wir für den Hauptbösewicht "ec2-52-3-105-23.compute-1.amazonaws.com" (IP: 52.3.127.144), der sich auf er Website des Bekannten schon in früheren Monaten hervorgetan hatte, einen Eintrag bei https://www.abuseipdb.com/ und http://ipaddress.com/blacklist-check/:

Und auch hier ist der ungebetene Gast des norwegischen Bekannten zu finden: https://myip.ms/view/blacklist/872644496/52.3.127.144 und http://whatismyipaddress.com/blacklist-check

Fazit: This guy is up to no good!

Generell gilt, dass bei anonymen Bot-/Crawler-Systemen, die unter Amazon AWS gehostet sind und die Daten von Webseiten komplett herunterladen, Vorsicht geboten ist.

Unser Plagegeist gehört ferner zu einem Bot-Netz namens "ltx71":
https://udger.com/resources/ua-list/bot-detail?bot=ltx71
https://myip.ms/view/web_bots/1239532/Known_Web_Bots_ltx71_http_ltx71_com.html

Was Gutes ist über "ltx71" im Internet nicht in Erfahrung zu bringen. Die "Homepage" beinhaltet nur 2 Sätze: Ja, wir crawlen das Netz, aber für Sicherheitszwecke. Echt? Menschheitsfreunde? Auch ansonsten findet man auffallend wenig:
http://review.easycounter.com/ltx71-scam-report
http://www.diamantnetz.de/wzn/a_infos/botdestages.php
http://scamanalyze.com/check/ltx71.com.html
http://www.scamaider.com/is-ltx71.com-safe-legal.html

Der größte Traffic zu ltx71 kommt ferner angeblich von russischen Systemen. (Sagen Analyseseiten zu Domainen). Was immer das bedeutet ... Zudem umgehen ltx71-Crawler blockierende Anweisungen in einer evtl. angelegten "robots.txt"-Datei einer Zieldomäne. Alles nicht gut!

Bzgl. der Analyse verfährt man dann genauso mit den anderen, von webalizer ausgewiesenen dubiosen Datengreifern. In unserem Fall stellte sich heraus, dass ein weiterer Besucher auch zu ltx71 gehört.

Für mich gilt in einer solchen, nicht völlig klaren Situation die Leitlinie: Es gibt keine Freunde im Internet.

Schon gar nicht, wenn deren Systeme meine teuer bezahlten Ressourcen für dubiose Zwecke verbrauchen würden.

Gegenmaßnahmen?

Wir konnten unserem norwegischen Bekannten jedenfalls Bericht erstatten und erste Hinweise geben. Kümmern muss sich nun sein Provider.

Nur der Vollständigkeit halber: Sperren könnte man die dubiosen Crawler-Bots zunächst mal über Einträge in einer ".htaccess"-Datei im Hauptverzeichnis auf dem Webserver nach dem Muster

order allow,deny
deny from 52.3.127.144
deny from 52.23.169.223
deny from 52.207.224.143
deny from 54.225.29.79
deny from 52.3.105.23
deny from 54.172.241.121
deny from 104.197.241.64
allow from all

Das wird auf Dauer bei einem Botnetz aber nicht viel helfen; es werden im nächsten Monat mit Sicherheit andere IP-Adressen auftauchen. Dann muss man zu anderen Mitteln greifen, die aber nicht Gegenstand dieses Posts sein sollen.

Jedenfalls kann man Betreibern von Websites, deren Ressourcen in ungewöhnlicher Weise mit Beschlag belegt werden, nur raten, sich die Logs der betroffenen Websites regelmäßig und genau anzusehen. Dabei kann der sehr einfache durchzuführende Einsatz von webalizer bereits erste wertvolle Erkenntnisse zeitigen.

Links

http://www.webalizer.org/
http://www.techrepublic.com/article/analyzing-web-sites-with-webalizer/
https://lf.net/support/techinfo/webserver/webalizer.php
http://www.linux-community.de/Internal/Artikel/Print-Artikel/LinuxUser/2011/04/Zugriffsdaten-auswerten-mit-Webalizer
https://privatstrand.dirkschmidtke.de/2011/05/10/webalizer-auf-logfiles-loslassen/

Opensuse Leap 42.1, Apache 2.4, Nagios-Modul und veraltete Access Right Syntax

Vor kurzem hatte ich das zweifelhafte Vergnügen, einen virtualisierten LAMP-Server von Opensuse 13.1 auf Opensuse Leap 42.1 zu hieven. Das ging zu meiner Überraschung weitgehend problemfrei über die Bühne. Eine kleine Besonderheit gab es aber schon.

Problem mit Apache 2.4 und der Konfiguration des Nagios-Moduls

Das Problem, dass bei der Umstellung auftauchte, war der Übergang des Apache-Servers zu einer neuen Version (2.2 => 2.4). Auf dem alten Server lief auch das Nagios-Modul für Apache mit. Nach dem Upgrade auf Opensuse Leap 42.1 verweigerte Apache den Start.

lamp:~ # systemctl start apache2.service 
Job for apache2.service failed. See "systemctl status apache2.service" and "journalctl -xn" for details.
xlamp:~ # systemctl start apache2.service 
Job for apache2.service failed. See "systemctl status apache2.service" and "journalctl -xn" for details.

 
und

lmp:~ # systemctl status apache2.service 
apache2.service - The Apache Webserver
   Loaded: loaded (/usr/lib/systemd/system/apache2.service; disabled)
   Active: failed (Result: exit-code) since Wed 2016-10-19 17:47:09 CEST; 37s ago
  Process: 2279 ExecStop=/usr/sbin/start_apache2 -DSYSTEMD -DFOREGROUND -k graceful-stop (code=exited, status=1/FAILURE)
  Process: 2272 ExecStart=/usr/sbin/start_apache2 -DSYSTEMD -DFOREGROUND -k start (code=exited, status=1/FAILURE)
 Main PID: 2272 (code=exited, status=1/FAILURE)

Oct 19 17:47:09 lmp start_apache2[2272]: AH00526: Syntax error on line 15 of /etc/apache2/conf.d/nagios.conf:
Oct 19 17:47:09 lmp start_apache2[2272]: Invalid command 'Order', perhaps misspelled or defined by a module ...ation
Oct 19 17:47:09 lmp systemd[1]: apache2.service: main process exited, code=exited, status=1/FAILURE
Oct 19 17:47:09 lmp start_apache2[2279]: AH00526: Syntax error on line 15 of /etc/apache2/conf.d/nagios.conf:
Oct 19 17:47:09 lmp start_apache2[2279]: Invalid command 'Order', perhaps misspelled or defined by a module ...ation
Oct 19 17:47:09 lmp systemd[1]: apache2.service: control process exited, code=exited status=1
Oct 19 17:47:09 lmp systemd[1]: Failed to start The Apache Webserver.
Oct 19 17:47:09 lmp systemd[1]: Unit apache2.service entered failed state.
Hint: Some lines were ellipsized, use -l to show in full.

 

Problemlösung 1 - Korrektur des Files nagios.conf

Die Ursache dieses Problems liegt in der Anweisungssyntax der Konfigurationsdatei zum Nagios-Modul und nicht im Nagios-Modul selbst. Die Anweisung zu den Zugangsrechten für Webserver-Verzeichnisse sind zwar noch für Apache-Versionen < 2.4 gültig; nicht aber für die Version 2.4.

Nehmen wir als Beispiel die Direktiven zu einem Verzeichnis aus der Datei "/etc/apache2/conf.d/nagios.conf":

   
<Directory "/usr/lib/nagios/cgi">
#  SSLRequireSSL
   Options ExecCGI
   AllowOverride None
   Order allow,deny
   Allow from all
#  Order deny,allow
#  Deny from all
#  Allow from 127.0.0.1
   AuthName "Nagios Access"
   AuthType Basic
   AuthUserFile /etc/nagios/htpasswd.users
   Require valid-user
</Directory>

Hier werden die Zugangsrechte in klassischer Manier durch die Statements

   Order allow,deny
   Allow from all

geregelt. Diese Statements sind unter Apache 2.4 aber nicht mehr zu verwenden!

Nähere Informationen zur neuen Syntax liefert die Dokumentation unter:
https://httpd.apache.org/docs/2.4/upgrading.html

Die obige Sequenz ist - falls man die Zugriffsberechtigung tatsächlich so handhaben will - durch das Statement

Require all granted

zu ersetzen. Also

   
<Directory "/usr/lib/nagios/cgi">
#  SSLRequireSSL
   Options ExecCGI
   AllowOverride None
#	
   Require all granted 
   #   Order allow,deny
   #   Allow from all
#
#  Order deny,allow
#  Deny from all
#  Allow from 127.0.0.1
   AuthName "Nagios Access"
   AuthType Basic
   AuthUserFile /etc/nagios/htpasswd.users
   Require valid-user
</Directory>

Die auskommentierte Sequenz

#  Order deny,allow
#  Deny from all
#  Allow from 127.0.0.1

wäre übrigens zu ersetzen durch

Require host 127.0.0.1

Führt man die vorgeschlagenen Änderungen für alle Directories in der "nagios.conf" durch, so läuft der Neustart u.U. erfolgreich. In meinem Fall war das nicht so, da ich natürlich auch in anderen Konfigurationsfiles (u.a. zu Webdomainen) weitere Access Right Statements mit alter Syntax eingefügt hatte. Hat man auch die dortigen Fehler korrigiert, läuft Apache2 wieder.

Problemlösung 2 - Nutzung eines Kompatibilitätsmoduls

Die Seite https://httpd.apache.org/docs/2.4/upgrading.html empfiehlt, wenn möglich, alle Änderungen auf einen Schlag durchzuführen. Das kann je nach Apache-Host und selbst eingeführten Zugangsrechten für die implementierten Web-Domainen aber aufwändig werden.

Ist einem diese Arbeit erstmal zu viel und will man nach dem Upgrade zunächst nur den Start des Apache-Servers trotz der neuen Syntax sicherstellen, so kann man das Modul "mod_access_compat" zu den Modulen hinzufügen, die der Apache-Server laden soll.

Hierzu benutzt man z.B. das Kommando "a2enmod" (s. etwa http://www.sysadminslife.com/linux/aktivierte-apache-module-anzeigen-deaktivieren-aktivieren/.
Unter Opensuse kann man die Module aber auch in einer entsprechenden Zeile der Datei "/etc/sysconfig/apache2" hinterlegen; also z.B.:

APACHE_MODULES="actions alias auth_basic authn_file authz_host authz_groupfile authz_user autoindex cgi dir env expires include log_config mime mod_access_compat mod_rewrite negotiation setenvif ssl userdir php5 reqtimeout authn_core authz_core version"

Viel Spaß weiter beim Betrieb von Apache!

Apache Rewrite für zwei Domänen, die gemeinsame Datei-Ressourcen nutzen

Gestern wurden wir mit zwei Websites konfrontiert, die wir um einen Blog ergänzen sollten. Die Webserver-Installation, die wir vorfanden, war interessant und hat uns ein wenig beschäftigt:

Zwei Domain-Namen (alpha.de und beta.de) waren beim Hosting-Provider mit ein und demselben Webserver-Verzeichnis verbunden. Dieses wiederum wies zwei Unterverzeichnisse auf, in denen sich vor allem HTML-Seiten zu den verschiedenen Domänen befanden. Die Idee hinter diesem Setup war wohl, von den Webseiten beider Domänen aus gemeinsame Datei-Ressourcen im Hauptverzeichnis zu nutzen.

Setup zur Nutzung gemeinsamer Datei-Ressourcen durch zwei Web-Domänen auf demselben Webserver

Nennen wir das Hauptverzeichnis mal dir_domains und die Subverzeichnisse dir_alpha und dir_beta.

Die Webseiten von alpha.de und beta.de nutzen gleiche Datei-Ressourcen (CSS-Dateien, Javascripts, PHP-Programme, ...). Entsprechende Verzeichnisse fanden sich unter dir_domains:

dir_domains (Webserververzeichnis für Domains alpha/beta)
|__css
|__js
|__php
|__index.php
| ....
|
|__dir_alpha
|        |__index.html
|        |...(HTML-Dateien für die Domäne beta.de)
|        | ....
|__dir_beta
         |__index.html
         |... (HTML-Dateien für die Domäne beta.de)
         |...

Die Datei index.php übernahm die Zugangssteuerung für die Startseiten: Je nach Domain-Anforderung (alpha.de oder beta.de) des Users wurde dieser auf die jeweilige Index-Seite unter dir_alpha oder dir_beta umgelenkt. So weit, so gut - oder eher so schlecht ....

Nach Inaugenscheinnahme der beiden Domänen im Internet war mir klar, warum das so aufgesetzt worden war:

Die Webseiten unter alpha.de bzw. beta.de haben einen ganz ähnlichen Aufbau und nutzen gleiche PHP-Programme und Scripts. Da bei der Anforderung von Ressourcen wie CSS-/JS-/PHP-Dateien Domaingrenzen in der Verzeichnisstruktur des Web-Servers normalerweise nicht überschritten werden dürfen, waren die Web-Designer gezwungen gewesen, beiden Domänen dasselbe Hauptverzeichnis des gehosteten Webserver-Accounts zuzuweisen. Zur Kompensation musste eine Art Umlenkung auf die jeweiligen Verzeichnisstrukturen integriert werden. (Anmerkung am Rande: Die Domängrenzen, im Sinne von Verzeichnisgrenzen, gelten übrigens nicht für Include-Dateien, die in PHP-Programmen nachgeladen werden. Solche Include-Dateien kann man ruhig oberhalb des Domainverzeichnisses unterbringen!).

Was war am Setup schlecht?

Während die Nutzung gemeinsamer Ressourcen durchaus zu befürworten ist, war die "Umlenkung" durch das PHP-Skript schlecht gelöst. Sie funktionierte eigentlich nur für den Aufruf einer der beiden Domän-Namen selbst (Umlenkung auf die jeweilige index.html-Seiten). Die Navigation innerhalb der Webseiten einer Domäne war über relative Pfade gelöst; sobald ein User sich einmal innerhalb einer Domäne bewegte, funktionierte deshalb alles aus Nutzersicht alles bestens.

Aber: Der Aufruf einer spezifischen Seite einer Domäne über eine direkte Eingabe in die Adresszeile des Browsers - z.B. http://alpha.de/infos/impressum.html - funktionierte mit dem vorhandenen PHP-Script nicht. Das Script index.php kümmerte sich nur um die Index-Seiten der Domänen. Es wurde als Index-Datei ja nur dann aktiv, wenn eine der Domän-Adressen alpha.de oder beta.de ohne weitere Zusätze im Browser aufgerufen wurde.

Lösungsansatz über Apache Rewrite

Bei dem gehosteten Webserver handelte es sich um einen Apache-Server. Eine saubere Lösung für den gewünschten Setup-Ansatz mit geteilten Datei-Ressourcen besteht dann natürlich darin, das Apache Rewrite-Modul (mod_rewrite) zu nutzen. Die Servereinstellungen beim Provider waren so, dass die Rewrite Engine über lokale ".htaccess"-Dateien aktiviert und gesteuert werden konnte. Wir haben dann folgenden einfachen Vorschlag umgesetzt:

Inhalt der .htaccess-Datei für das Verzeichnis dir_domains:

Options +FollowSymLinks 
RewriteEngine On 
RewriteBase /

RewriteRule ^alpha/(.*)$ - [L]
RewriteRule ^beta/(.*)$ - [L]

RewriteRule ^css/(.*)$ - [L]
RewriteRule ^images/(.*)$ - [L]
RewriteRule ^php/(.*)$ - [L]
RewriteRule ^script/(.*)$ - [L]

RewriteCond %{SERVER_NAME} alpha.de [OR]
RewriteCond %{SERVER_NAME} www.alpha.de
RewriteRule ^$ alpha/index.html [L]

RewriteCond %{SERVER_NAME} alpha.de [OR]
RewriteCond %{SERVER_NAME} www.alpha.de
RewriteRule ^(.*)$ alpha/$1 [NC,L]

RewriteCond %{SERVER_NAME} beta.de [OR]
RewriteCond %{SERVER_NAME} www.beta.de
RewriteRule ^$ beta/index.html [L]

RewriteCond %{SERVER_NAME} beta.de [OR]
RewriteCond %{SERVER_NAME} www.beta.de
RewriteRule ^(.*)$ beta/$1 [NC,L]

 
Die ersten 2 Rewrite-Regeln sorgen dafür, dass keine Umlenkung mehr vorgenommen wird, wenn man sich bereits im Verzeichnisbereich der Seite befindet. Dieser Vorspann ist wichtiger, als man meinen möchte: die nachfolgenden Regeln würden für sich allein zu einer unbegrenzten Iteration von Rewrites führen!

Die nächsten 4 Regeln sorgen dann dafür, dass Verweise auf die gemeinsam genutzten Ressourcen-Verzeichnisse und zugehörige GET-Anforderungen an den Server unangetastet bleiben. Diese Verzeichnisse werden ja aus dem HTML-Code der Webseiten unter dem alpha- bzw. dem beta-Sub-Verzeichnis referenziert; z.B. über relative Pfade.

Danach kommen die eigentlichen Umlenkungsregeln. Wir haben hier die Grundregel befolgt, dass eine oder mehrere Rewrite Conditions sich nur und ausschließlich auf die nächste Rewrite Rule beziehen - also auf genau eine Rewrite Rule! Das wird in der hektik oft übersehen; es gibt keine native Klammerung mehrerer Rewrite Rules zu Rewrite Conditions. Allerdings kann man mit Negationen der Bedingungen und Skip-Zusätzen hinter den Rewrite-Regeln tricksen. Um das Verständnis nicht zu erschweren, haben wir hier auf solche Hacks verzichtet.

Wird keine Dateiname angegeben - ist also der Pfad hinter dem Domain-Anteil leer - wird auf die jeweilige Index-Seite umgelenkt. Sind konkrete Webseiten einer Domäne angefordert, wird auf die gewünschte Datei im jeweiligen Unterverzeichnis verwiesen.

Das war es schon; die Datei index.php kann und sollte danach gelöscht werden. Unser Kunde kann nun 2 Domänen im gleichen Webserververzeichnis nutzen und zwischen beiden Implementierungen gemeinsame Ressourcen teilen. Eigentlich eine nette kleine Geschichte, die ich vielleicht auch mal für eigene Sites nutzen werde - Apache sei Dank!