HTTP_HOST mit mod_rewrite verändern

Ich möchte heute einen mod_rewrite - Move veröffentlichen, den ich so im Internet (als ich ihn selber brauchte ... *gnaaahr* .. ;) ) nicht gefunden habe.

Erstmal: Worum geht's?
Ich hatte auf der Arbeit folgende Aufgabe: Einer unserer Kunden hat mehrere Domains. Unter jeder dieser Domains gibt es einen DNS-Eintrag für jeden Server des Kunden. Zum Beispiel: server1.domain1.de , server1.domain2.de , ... etc. In  Einträgen mit gleichem Servernamen (server1) ist immer dieselbe IP hinterlegt.

Nun tauchten teilweise doppelte Einträge bei Suchmaschinen auf, wodurch das Ranking negativ beeinflusst wird. Es gab zum Beispiel diese beiden (fiktiven) Hits auf denselben Suchausdruck: http://server1.domain1.de/gartenzubehoer.html und http://server1.domain2.de/gartenzubehoer.html. Das ist natürlich eher nicht erwünscht.

Die Aufgabe bestand nun also aus 3 Punkten:

  1. Es sollen alle Anfragen von allen Domains auf eine einzige Hauptdomain mit einem RedirectPermanent (301) umgeleitet werden.
  2. Es muss erreicht werden, das der Subdomain - Teil (server1) mit übernommen wird und der Hauptdomain vorangestellt wird.
  3. Der URI-Teil nach dem Hostteil (/gartenzubehoer.html) muss in der neuen URI auch wieder angehangen werden.

Nun bietet mod_rewrite es in RewriteRule - Anweisung aber irgendwie nur an, den Teil nach dem Hostteil zu verändern/zu übernehmen. Somit hätte ich nur die Möglichkeit auf einen einzigen Server umzuleiten.
Es gibt auch die RewriteCond - Anweisung. Hiermit kann man auch die Variable HTTP_HOST auf bestimmte Inhalte hin überprüfen, jedoch nicht verändern.

Wie bekommt man es nun hin die Anfrage wie beschrieben zu manipulieren?

Lösung: Man kann mit einem regulären Ausdruck Werte aus der RewriteCond - Anweisung in der RewriteRule - Anweisung wiederverwerten!
Es folgt das Beispiel für die beschriebene Anforderung:

RewriteEngine On
RewriteCond %{HTTP_HOST} \^(.*)\.domain.\.de\$ [NC]
RewriteRule \^(.*)\$ http://%1\.domain1\.de\$1 [R=301,L]

Das wars! Das fiese: RewriteCond Speichert seine Pattern in Variablen, die mit %N angesprochen werden und RewriteRule in Variablen, die mit \$N angesprochen werden! Mit diesem Wissen ist es eigentlich schon wieder ein Kinderspiel, wie man sieht.

Ich gehe die Zeilen schnell (!) durch:

Zeile 1: Aktiviert nur das mod_rewrite .

Zeile 2: RewriteCond ist eigentlich dazu da, um einen Request vor der Umformung zunächst mal durch verschiedene Prüfungen gehen zu lassen. Nur wenn alle RewriteCond Tests erfolgreich waren, wird die Manipulation durch RewriteRule vorgenommen. Hier dient uns die Anweisung jedoch dazu den HTTP_HOST auszulesen und in der Variable %1 zu speichern. Dieses wird durch die () erreicht (Siehe: Reguläre Ausdrücke). Die Option [NC] steht für "not casesensitive" und bewirkt, das es egal ist, ob jemand eine beliebige Kombination aus Groß- und Kleinschreibung in der URL verwendet.

Zeile 3: RewriteRule definiert nun wie genau die Anfrage manipuliert werden soll. der zweite Teil nimmt sich einfach alle Zeichen, die hinter dem Hostteil kommen und speichert sie in der Variablen \$1. Anschließend wird das Ziel definiert. Hier werden beide Variablen, %1 und \$1, wieder verwertet. Die Optionen [R=301,L] besagen nun, das es sich um eine Umleitung (Redirect) des Types 301 (permanent) handelt, und das dieses die letzte Regel sein soll, die angewendet wird (L).

Das ganze hat mich über 2 Stunden gekostet. Hab offenbar immer wieder übersehen, das es sich um zwei unterschiedliche Variablenregister bei %N und \$N handelt.
Ich hoffe das dieses jemandem diese Zeit spart ;)

Wie immer freue ich mich sehr über ein kurzes Feedback in Form eines Kommentars :)

Teilen per: TwitterEmail


Apache - Anfragen ohne www. umleiten

Suchmaschinen bewerten eine Seite und deren Inhalt anhand vieler, teilweise dem normalen User garnicht bewusste, Kriterien um den PageRank einer Seite zu bestimmen, bzw. deren Relevanz zu einem Suchbegriff.
So wird es z.B. von Suchmaschinen inzwischen geahndet, wenn ein und derselbe Inhalt über zwei verschiedene Adressen erreichbar ist.
Es ist für eine Suchmaschine bereits ein Unterschied, ob eine Seite ohne www. Subdomain-Präfix (z.B. http://webseite.de ) oder mit www. Subdomain-Präfix (z.B. http://www.webseite.de ) aufgerufen werden kann. Das ist auch soweit korrekt, da in verschiedenen Subdomains ja vollkommen andere Inhalte bereitgestellt werden können. Im weitesten Sinne können sich ja gar vollkommen andere Server hinter jeder Subdomain verbergen. Und www ist letzten endes auch nur eine Subdomain. Aus Sicht der Bewertungslogik einer Suchmaschine, handelt es sich bei einer Domain http://webseite.de und http://www.webseite.de um völlig verschiedene Webseiten.

Man nehme nur mal an das wäre nicht so. Dann könnte sich ja jeder Kinz und Kunz, der nur ein einziges Mal eine HTML Seite mit allen möglichen Suchbegriffen von Abakus bis Zypern hochgeladen hat, beliebig viele (Sub-/)Domains auf diese HTML Seite zeigen lassen, und somit quasi alleine in den Suchergebnissen auftauchen. Somit verdrängen Website-Spammer ja fast alle anderen relevanten Seiten, die ordnungsgemäß nur eine Domain auf ihre Webpräsenz zeigen lassen, völlig aus den Suchergebnissen.

Man kann dieser Herabstufung der eigenen Präsenz jedoch ganz einfach entgegenwirken: Indem man einfach alle Anfragen an http://webseite.de nach http://www.webseite.de umleitet.
Hierzu bietet sich das Apache Modul mod_rewrite an. Es handelt sich hierbei um ein sehr mächtiges Modul, welches bestimmte Adressen zu beliebigen anderen Adressen umformen kann. Es hat dabei seine ganz eigene Syntax um hierfür Regeln zu definieren. Diese ist viel zu mächtig um sie hier auch nur annähernd zu erklären; wen es interessiert, der kann die Anleitung zu diesem Modul hier finden.
An dieser Stelle sei nur erklärt, wie man seinen Apache Webserver dazu bringen kann, die URL ohne www. zu einer Adresse mit www. umzuformen:

RewriteEngine On
RewriteCond %{HTTP_HOST} \^webseite\.de\$ [NC]
RewriteRule \^(.*)\$ http://www\.webseite\.de\$1 [R=301,L]

Dieser Absatz kann per .htaccess Datei, per vHost oder global in der Apache Konfiguration eingefügt werden. Nicht vergessen den Webserver neu zu starten und ausprobieren!
Ich erkläre die drei Zeilen wie gesagt nur ganz grob, da ich keine Lust habe der 1.000. Wiederkäuer der Moduldokumentation zu werden:

Zeile 1:
Hier wird die Rewrite Engine eigentlich nur aktiviert, damit das Modul überhaupt angesteuert werden kann.

Zeile 2:
Mit "RewriteCond" wird das Muster definiert, welches, sofern es in der eingegebenen Adresse vorkommt, nach den Bedingungen der Direktive "RewriteRule" schliesslich umgeformt werden soll. %{HTTP_HOST} ist eine Variable, die vom Modul mod_rewrite zur Laufzeit der Rewrite Engine automatisch erzeugt wird. Sie beinhaltet die in der HTTP-Protokollanfrage angegebenen Hostnamen.
Dadurch das diese Variable an der 1. Position nach "RewriteCond" steht, wird dieses bei der Anfrage nach dem an der 2. Position stehendem Muster durchsucht.
Das Muster an der 2. Position nach "RewriteCond" ist ein regulärer Ausdruck; eine weitere Technik, die zu erklären hier den Rahmen sprengen würde. Er besagt, das die Zeichenkette in der Variable %{HTTP_HOST} genau "webseite.de" sein muss; ohne ein Zeichen davor und ohne ein Zeichen dahinter. ("/unterseite.html" zum Beispiel ist nicht Teil dieser Veriablen, da es hinter dem "/" steht). Die Zusatzoption [NC] an der 3. Position nach "RewriteCond" bedeutet, das Groß- und Kleinschreibung in der URL egal ist. (NC = Non Casesensitive).

Zeile 3:
Diese Zeile definiert letzten Endes die Regel, nach der die Anfrage modifiziert werden soll. Es handelt sich zunächst wieder um einen regulären Ausdruck, der besagt, das die gesamte Zeichenkette, welche durch "RewriteCond" analysiert wurde, durch "http://www.webseite.de/urspruengliche/anfrage.html" ersetzt werden soll ("/ursprüngliche/anfrage.html" ist selbstverständlich nur ein Beispiel. Hier wird immer eingefügt, was nach der TLD angegeben worden ist). Dabei soll der HTTP Statuscode 301 (Permanent Redirect) in der Antwort versendet werden und dieses ist die letzte Regel ([L]). Danach sollen keine mehr folgen. So werden Endlosschleifen vermieden und der Arbeitsbereich der RewriteEngine klar abgegrenzt.

Teilen per: TwitterEmail


Gesucht wird: fastlogres

Sowas habe ich echt noch nicht erlebt:

Auf unserem Server für Webseiten-Statistiken liegt ein Programm namens "fastlogres" im Ordner /usr/bin . Es handelt sich dabei um ein SUSE Linux System. Ein "rpm -qal | grep fastlogres" zeigt mir, das das Programm aus keinem RPM Paket stammt.
Normalerweise legen wir selbst kompilierte Sourcen in einem bestimmten Unterverzeichnis ab, für genau so einen Fall. Jedoch ist das in diesem Fall nicht passiert.

Eine Suchmaschienen-Recherche bringt mir leider keinen Erfolg. In keiner einzigen (!) Suchmaschiene finde ich etwas, das auf dieses Programm hinweist.

Es gibt leider keinen Switch bei dem Programm und keine Manpage, in der eine URL steht. Es gibt lediglich den switch -v zur Ausgabe der Version. Und diese Ausgabe lautet lediglich:

fastlogres 0.2.0

Das Programm löst IPs aus Apache Logfiles zu DNS Namen auf. Dieses tut es deutlich schneller als es der in AWstats eingebaute DNS Resolve Mechanismus tut. Ein Referenzlogfile eines Monats von einer unserer Seiten wird von AWstats in 57 minuten und 39 Sekunden ausgewertet. Dem gegenüber steht fastlogres mit nur 25 minuten und 53 Sekunden; also mehr als doppelt so schnell!

Genau das ist mein Ziel: Diesen Flaschenhals etwas zu "dehnen".

Bevor ich dieses Programm gefunden habe, bin ich auf "adnslogres", als Teil der GNU adns Bibliothek aufmerksam geworden. Diese benötigt für dasselbe Logfile

Daher: Bis jetzt ist fastlogres mit abstand das schnellste Programm!

Nur finde ich es nirgendwo im Netz :(
Es kann doch nicht sein, das auf unserem Server ein Programm läuft und derart super funktioniert, ohne das man im Internet auch nur einen Hinweis darauf findet.

Wenn jemand dieses Tool kennt, wäre ich höchst dankbar, wenn er mir hier einen Hinweis geben könnte.

Auch Alternativen, die die beschriebene Aufgabe erfüllen können, sind sehr gerne gesehen! :)

Teilen per: TwitterEmail


mod_auth_mysql Problem bei Migration von apache1 zu apache2

Neeeee - was ärgert mich sowas:

Ich bin seit 2 Stunden dran um einen Fehler bei der mod_auth_mysql Authentifikation des Apache2 Webservers zu finden, und die einzige Webresource in der ich fündig werde (nach 2 Stunden, wohlgemerkt) ist ein italienisches Privatblog.

Ich hatte das Problem, das nach der Umstellung nur noch folgender Fehler in Logfile geschrieben wurde:

(9)Bad file descriptor: Could not open password file: (null)

Mich hatte es zwar schon stutzig gemacht, das da etwas von einer Passwort Datei stand, aber kapiert habe ich es soweit erstmal nicht, da ich nicht wusste ob die MySQL Tabelle evtl. aus Sicht des Servers tatsächlich eine Art "Passwortdatei" ist.

Auf jeden Fall lag es letzten endes daran, das Apache2 authz_user standardmäßig aktiviert, was der Apache1 nicht tut. Also erwartet er auch die Übergabe einer Passwortdatei. Diese war nicht definiert, also spuckt er die obige Fehlermeldung aus.

Behoben werden kann es ganz einfach, indem in der Apache2 Server-Config (httpd.conf, .htaccess, etc.) die folgende Einstellung gesetzt wird:

AuthBasicAuthoritative Off

Das war's! :)

(01.09.2008)
PS:

Nach der oben beschriebenen Methode kann man sich zwar wieder über niedriger priorisierte Authentifikationsmodule wie z.B. mod_auth_mysql anmelden, es erscheint im error-log jedoch nach wie vor die Meldung

(9)Bad file descriptor: Could not open * file: (null)

Dieses kann man beheben, indem man zusätzlich zu "AuthBasicAuthoritative Off" die folgenden zwei Einstellungen setzt:

AuthUserFile /dev/null
AuthGroupFile /dev/null

War mir irgendwie erst heute aufgefallen, das das nach wie vor geschrieben wird ... \~:)

Teilen per: TwitterEmail


Wenn Seiten permanent Umziehen

Ha, da haben wir den ersten Fall, der es in meinen Augen würdig ist zu dokumentieren! :)

Bevor Cap und ich diesen jetzigen Server für unsere Domains zoosau.de und tittentiere.de hatten, und Cap seine damalige Seite auf einem anderen Server gehostet hatte, fand ich es eine gute Idee die Benutzerverwaltung seines Member Bereiches auf meinem Server laufen zu lassen, da ich nur da ausreichende Möglichkeiten hatte, die CGI Scripte abzulegen, auszuführen und die dazu notwendigen Servereinstellungen vorzunehmen.

Ich benutze dazu das mod_userdir des Apache Webservers.

Hierdurch refferenzieren immer noch ziemlich viele Links und Seiten auf die URL http://www.zoosau.de/\~cap/. Das verfälschte bis jetzt immer die Statistiken, da Hits, die eigentlich für Cap waren, unter meiner Zoosau verarbeitet wurden.

Hierfür gibt es eine Funktion "Redirect Permanent" im Apache Modul mod_userdir.

Folgende zwei Einträge in der Konfiguration der Domain zoosau.de auf dem Webserver helfen hier weiter:

RedirectPermanent /~cap http://www.tittentiere.de/ RedirectPermanent /~ww http://www.zoosau.de/

Teilen per: TwitterEmail