Das Putzlowitsch Test- und SEO-Blog

WordPress mit Permalinks – den Webserver entlasten

Wie WordPress Permalinks verarbeitet

Durch Permalinks bekommen Artikel und Seiten lesbare URLs und auch Struktur. Alle Artikel in der Kategorie ‚Wordpess‘ können mit schnurpsel.de/themen/wordpress/ aufgerufen werden, das Monatsarchiv für Juli 2010 mit schnurpsel.de/date/2010/07/.

Auf dem Webserver existiert aber kein Verzeichnis /themen/wordpress/ oder /date/2010/07/. Damit die Seiten trotzdem aufgerufen werden können, erstellt WordPress eine einfache Regel für das Rewrite-Modul des Apache-Webservers:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Diese drei Zeilen führen dazu, das alles, was nicht tatsächlich als Datei oder Verzeichnis auf dem Server existiert, einfach an die index.php von WordPress durchgereicht wird. WordPress kümmert sich nun darum, ob es z.B. eine Kategorie „WordPress“ gibt, stellt die Liste mit den passenden Artikeln zusammen und gibt sie aus.

Was es alles nicht gibt

Im Moment sind wohl mal wieder ein paar Bots oder Skriptkiddies unterwegs, die einfach versuchen, irgendwelche php-Skripte aufzurufen, um mögliche Sicherheitslücken ausnutzen zu können. Das sieht dann etwa so aus:

/scripts/setup.php
/pma/scripts/setup.php
/phpMyAdmin/scripts/setup.php
/phpmyadmin/scripts/setup.php
/myadmin/scripts/setup.php

Solche Dateien gibt es hier allerdings nicht. Auch andere Sachen können zu fehlerhaften Aufrufen führen, z.B. Standard-Icons wie favicon.ico oder apple-touch-icon.png, die manche Browser einfach aufrufen oder durch Nutzer aus der Bildersuche falsch kopierte BILd-URLs.

Durch die für die Permalinks notwendigen mod_rewrite-Regeln werden alle dies Aufrufe nun an WordPress weitergeleitet. WordPress wird geladen, stellt eine Datenbankverbingung her, klappert die internene Rewriteregeln ab um schließlich nur festzustellen, daß es mit dem Aufruf nichts anfangen kann. Dann gibt WordPress schließlich auch nur eine Fehlerseite aus, die möglicherweise auch noch aufwändig gestaltet ist und unnötig viel Daten als Antwort zurücküberträgt.

WordPress und den Webserver entlasten

Damit nun nicht WordPress wegen jeder Kleinigkeit behelligt werden, kann man eine spezielle Regel der WordPress-Regel vorschalten, die einfach gegebenfalls die Abarbeitung der Rewrite-Regeln beendet:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule \.[^\.]+$ - [L]
</IfModule>

Die Idee dabei ist, daß alle Permalink-URLs normalerweise keine Dateierweiterung wie .html, .jpg oder .php haben. Falls nun eine Datei nicht existiert (RewriteCond) und diese Datei mit einem Punkt und mindestens einem weiteren Zeichen endet, wird die Abarbeitung der Regeln an dieser Stelle beendet (RewriteRule). Diese Zeilen müssen vor den WordPress-Regeln stehen.

WordPress bekommt diese Aufrufe nicht mehr zu sehen, der Fehler wird einfach vom Webserver behandelt. Hier kommt dann auch eine konfigurierte und vorhanden benutzerdefinierte Fehlerseite zu Anwendung.

Ich weiß, es gibt auch Blogger, die aus welchen Gründen auch immer, die Permalinks mit einem abschließenden .html konfiguriert haben. Aber auch das ist kein Problem, es muß nur eine Zeile hinzugefügt werden, welche die Regel für die Endung .html (oder eine andere) ungültig macht:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI}	!\.html$
RewriteRule \.[^\.]+$ - [L]
</IfModule>

Optimierte Version

Mann kann die zusätzlichen Bedingungen auch direkt in die WordPress-Rules einfügen. Nachteil hierbei ist aber, daß sie bei Änderungen an den Permalinkeinstellungen verloren gehen, weil WordPress den Block zwischen # BEGIN WordPress und # END WordPress neu schreibt:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI}	!\.[^\.]+$
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Die Version mit Endung .html:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI}	!\.[^\.]+$ [OR]
RewriteCond %{REQUEST_URI}	\.html$
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Plugin-Version

Angeregt durch die Kommentare von Ralf habe ich nun eine Plugin-Version fertig gestellt.

Download: 123 Rewrite Error 0.10

Das Plugin schreibt die Regeln beim Aktivieren, Deaktivieren und bei Änderungen an der Permalinkstruktur wie bei der Optimierten Version beschrieben automtisch mit den WordPress-RewriteRules in die .htaccess. Dabei wird auch gleich berücksichtigt, ob in der Permalinkstruktur eine Erweiterung wie .html angegeben wurde.

Fazit

Wieviel Serverlast oder Traffic durch diese Maßnahme eingespart wird, kann ich nicht sagen. Das hängt sicher auch vom Nutzungsprofil und der Konfiguration der Website ab. Aber warum sollte man solch eine einfache Möglichkeiten auslassen, um WordPress und dem Webserver das Leben ein bißchen leichter zu machen.

8 Kommentare »

Strato wird vernünfig, mod_rewrite funktioniert

Das ich das noch miterleben darf. Nachdem ja bereits vor einiger Zeit das memory_limit angehoben und der safemode ausgeschaltet wurde, ist nun eines der weiteren großen Ärgernisse beim Strato-Webhosting aus der Welt geschafft.

Seit kurzem unterstützt Strato das für Permalinks wichtige Modul mod_rewrite. Bisher mußte man sich da mit Tricks, wie einem vorangestellten index.php oder dem Fehler 404 Plugin behelfen. Jetzt funktioniert das einfach so, wie es von WordPress selbst vorgesehen ist, über ein paar mod_rewrite-Regeln.
Wenn Strato jetzt noch die Datenbank-Performance verbessert, könnte man aus WordPress-Sicht schon fast rundum zufrieden sein.

Nachtrag 09.04.2008: Seit heute findet man auch einen entsprechenden Artikel zu mod_rewrite in den Strato-FAQ.

29 Kommentare »