Kategorien
Blog

Sonderservice: WordPress um eine Verzeichnisebene nach oben verschieben

Svensonsan bastelt. Irgendwas klappt noch nicht so richtig. Ich habe Hilfe angeboten.

Wir stellen uns also vor, wir hätten ein WordPress (ganz normal, ohne Multisite-Funktion) auf einer Domain im Unterverzeichnis blog liegen. Das soll sich jetzt ändern, das „/blog“ soll aus allen URLs raus, die ganzen existierenden Links und Suchmaschinenergebnisse dürfen dabei aber nicht kaputt gehen. Der folgend beschriebene Weg dürfte der einfachste sein. Er funktioniert aber nur, wenn sich nicht gleichzeitig auch die Permalink-Struktur geändert hat:

Der Anfang liegt in der WordPress-Konfiguration. In der Datenbank oder wp-config.php müssen WP_HOME und WP_SITEURL auf die neue Adresse eingestellt werden. Jetzt funktioniert erstmal nichts mehr.

Als nächstes rücken die Dateien alle um ein Verzeichnis nach oben. Da ist es gut, wenn man Shellzugang zu seinem Webserver hat, denn nur mit ftp wird das beliebig eklig oder zumindest langwierig (abhängig davon, was den Server kann). Also zum Beispiel:

cd /var/www
mv htdocs htdocs.old
mv htdocs.old/blog htdocs

Jetzt funktionieren die neuen URLs aber die alten nicht mehr (dadurch sind wahrscheinlich auch alle Bilder kaputt etc. etc. — das war beabsichtigt, also keine Sorge). Wir legen deshalb in unserem Rootverzeichnis der Domain (im Beispiel /var/www/htdocs) einen neuen Ordner blog an und lassen Apache die Umschreibarbeit machen. In die Datei blog/.htaccess schreiben wir:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
</IfModule>

Dadurch werden alle angeforderten Dateien unterhalb von „/blog“ auf dieselbe Adresse ohne „/blog“ umgeleitet. Schon sollte alles wieder funktionieren. Jedenfalls habe ich so den Umzug von WordPress in einem Verzeichnis auf WordPress µ für die ganze Domain geschafft.

(Übung für Fortgeschrittene mit genug Adminrechten: den Ordner blog muss man nicht unbedingt im WordPress-Verzeichnis anlegen, er kann auch durch die Apache-Konfiguration von anderer Stelle eingeblendet werden.)

Kategorien
Blog

Mein Speed-Setup, Teil1: https

Vor einiger Zeit hatte ich mal mit der Beschleunigung dieses Blogs (und der anderen wazong-Seiten) beschäftigt. Dabei hatte ich mit Varnish schnell mittelgute Ergebnisse bekommen, es waren aber einige Fragen offengeblieben. Für einen Teil habe ich inzwischen Lösungen gefunden, bei anderen bastle ich noch.

Da war zuerst das access.log, in dem nur noch Zugriffe von 127.0.0.1 verzeichnet wurden. Dafür gibt es ein Apache-Modul, das den verbindenden Client durch den Inhalt des „X-Forwarded-For:“-Headers ersetzt (wo der herkommt, dazu später mehr). Debian hat’s praktischerweise als fertiges Paket herumliegen, so dass man das Problem mit:

apt-get install libapache2-mod-rpaf
cd /etc/apache2/mods-enabled
ln -s ../mods-available/rpaf.* .

erledigt hat.

Das https-Caching ist mit WordPress als Backend komplizierter; da WordPress viel mit vollständigen (auch selbst erzeugten) URLs arbeitet, wird man beim einfachen Ansatz (also einen TLS-Offloader vor den Proxy-Cache setzen) ständig auf die unsichere Verbindung umgeleitet. Die eine Seite wird also wirklich über die verschlüsselte Verbindung geladen, alle Bilder und StyleSheets aber schon wieder unverschlüsselt, und die Links auf des Seite führen auch alle zur unverschlüsselten Version.

Mein erster Ansatz war, nginx die TLS-Verarbeitung durchführen zu lassen (das ging gut damit) , und Links auf http://dentaku.wazong.de/ automatisch zu https://dentaku.wazong.de/ umschreiben zu lassen. Leider ist das nicht die einzige Domain, die auf diesem Server wohnt, und das zuerst geeignet erscheinende HttpSubModule kann leider keine regulären Ausdrücke verarbeiten und ist auch auf eine Ersetzungs pro Virtual Host beschränkt. Ich ließ also nginx wieder nginx sein (wer will schon einen kompletten Webserver vor einem anderen Webserver haben?) und kehrte zu einem zweiten Versuch mit Pound zurück.

In den folgenden Artikeln erkläre ich also ein Setup, das etwa so aussieht:

Kategorien
Blog

Firnis (oder: Das muss schneller gehen!)

Vor einiger Zeit (oh, ist ja auch schon wieder ein Jahr her) hat mich bei Martin Thielecke ein Artikel aufgeschreckt. Seitdem steht Webserver-Tuning auf meiner ToDo-Liste (die ist geduldig). Nachdem auch Google sagt, dass meine Webseite langsam ist:

(ok, die scheinen das auch nur mal im letzten Mai gemessen zu haben), musste da jetzt echt mal was passieren. Das soll hier also alles ein wenig schneller (und belastbarer) werden. Als ersten Schritt habe ich nach etwas Einleserei vor meinen Apache jetzt einen Varnish-Cache gestellt. Der läuft im Moment noch mit Standardeinstellungen, was ein paar Nachteile hat:

  1. Die Cache-Hit-Rate ist eigentlich miserabel: WordPress liefert seine Seiten mit minimaler Lebenszeit aus und setzt auch sehr gern Cookies. Beides verhindert bei normaler Konfiguration eine Zwischenspeicherung im Cache. Varnish lässt sich aber sehr fein einstellen, da sollte sich noch einiges machen lassen.
  2. Die Apache-Accesslogs sehen eher eigenartig aus: alle Anfragen kommen im Moment von 127.0.0.1, aber auch das sollte mit Konfiguration wieder in den Griff zu bekommen sein.
  3. https ist noch nicht beschleunigt, weil Varnish kein TLS spricht. Da habe ich schon ein wenig herumexperimentiert mit Pound, aber damit kommt die Information, dass über https zugegriffen wird, nicht bei WordPress an, so dass alle ausgegebenen Links (auch die zu StyleSheets und Bildern des Themes) wieder auf die unverschlüsselte Variante zeigen. Da weder Varnish noch Pound die Links im Vorübergehen umschreiben können, muss ich mir da was anderes einfallen lassen (ich lese gerade ein wenig über nginx, damit könnte das gehen).

Wenn ich eine gangbare Konfiguration gebastelt habe, dann schreibe ich mal eine Anleitung (wenn Euch hier umgekehrt irgendwas auffällt, das nicht richtig funktioniert, dann beschwert Euch).

Kategorien
Blog

Einrichtung eines SVN-Spiegelservers

Der Subversion-Server des Kunden ist der langsamste seiner Art. Das sorgt für Frust; nicht nur blickt man in Eclipse oft minutenlang auf „Pending…“, wenn man Teilbäume aufklappen möchte, es schlagen auch Hudson-Builds fehl, weil svn update nicht durchgelaufen ist.

Für Hudson könnte man sich behelfen, indem man mit svnsync eine lokale (readonly-)Kopie des Repositories einrichtete, aber in der Entwicklungsumgebung hilft das nicht weiter. Seit Subversion 1.5 ist es zum Glück möglich, das dav_svn-Modul im Apache so zu konfigurieren, dass schreibende Zugriffe direkt auf ein zentrales Repository (den Master) umgeleitet werden während lesende Operationen auf einer lokalen Kopie ausgeführt werden.

Die im Netz zu diesem Thema zu findenden Anleitungen gehen größtenteils davon aus, dass man Master- und Slaveserver unter seiner eigenen Kontrolle hat. Wir können aber am Master nichts konfigurieren und werden deshalb eine etwas sparsamere Variante einrichten müssen.

Voraussetzungen:

  • Apache (min. 2.2)
  • svn (min. 1.5)
  • Apache mod_dav_svn und mod_proxy (sowie Module, von denen die jeweils abhängen)
  • Apache mod_ssl (wenn das Master-Repository per https erreichbar ist)

Schritt 0:

Benutzer anlegen (nennen wir ihn mal svnsync), mit dessen Account später die Synchronisation laufen wird. Weil der sich den Zugriff auf das Repository mit dem Webserver teilen wird, habe ich ihn in einer gemeinsamen Gruppe angelegt.

Schritt 1:

Repository anlegen (als root):

svnadmin create /var/www/svn/projekt

Die einzelnen Benutzer müssen wir nicht anlegen, weil das Benutzermanagement und die Commitrechte weiterhin vom Masterserver verwaltet werden.

Schritt 2:

Schreibenden Zugriff aufs Repository für alle Benutzer außer svnsync verbieten. Das geht mit einem „pre-revprop-change“-hook:

#!/bin/sh
USER="$3"

if [ "$USER" != "svnsync" ]; then
    echo >&2 "Only the svnsync user can change revprops"
    exit 1
fi

exit 0

Schritt 3:

Synchronisation starten:

Als Benutzer svnsync muss man die Synchronisationsverbindung erst erstellen (init) und dann die erste Synchronisation durchführen (sync). Je nachdem, wieviele Revisionen es im Master-Repository schon gibt kann das seine Zeit dauern.

 svnsync init file:///var/www/svn/projekt https://subversion.kunde.de/svn/projekt
 svnsync sync file:///var/www/svn/projekt

Passwörter für das Master-Repository müssen in dieser Phase eventuell eingegeben werden und werden dann im Home-Verzeichnis des Synchronisationsbenutzers im .svn-Verzeichnis gespeichert — das ist also mit der notwendigen Vorsicht/Sicherheit zu behandeln.Ständige Synchronisation einrichten:

Da uns, wie gesagt, das Master-Repository nicht gehört, können wir es nicht dazu bringen, uns von Änderungen zu unterrichten. Den sync-Befehl lassen wir deshalb von cron einmal pro Minute ausführen:

* * * * * svnsync sync file:///var/www/svn/projekt > /dev/null 2>&1

Schritt 4:

Zugriff über Apache einrichten:

In schmerzhaften Versuchen musste ich feststellen, dass der Zugriff über den Spiegel nur dann zuverlässig funktioniert, wenn sich die beiden Server möglichst ähnlich sind. Mit verschiedenen Repository-URLs (also wenn der „Verzeichnisname“ des Spiegels sich vom Original unterschied) hatte ich z.T. seltsame Fehlermeldungen („405 Unsupported Operation“,…). Auch der Wechsel von https (auf dem Kundenserver) auf http sorgt für unerklärliches Verhalten bei Verschiebe- und Umbenennoperationen. Wenn das Master-Repository über https erreichbar ist, benötigt man aber ohnehin mod_ssl (und muss den Parameter „SSLProxyEngine“ auf „on“ stellen).

Module laden (dies ist der Mindestumfang, und die Syntax unterscheidet sich je nach Linux/Apache-Distribution):

LoadModule dav_svn_module mod_dav_svn.so
LoadModule proxy_module mod_proxy.so
LoadModule proxy_http_module mod_proxy_http.so
LoadModule ssl_module mod_ssl.so

Konfiguration (Schnipsel an für diesen Apache geeignete Stelle einfügen):

SSLProxyEngine on

<Location /svn/projekt>
    DAV svn
    SVNPath /var/www/svn/projekt
    SVNMasterURI https://subversion.kunde.de/svn/projekt
</Location>

Jetzt kann man mit dem schnellen lokalen Server statt mit der weit entfernten lahmen Ente arbeiten (aber Achtung: nur per http(s) zugreifen, sonst entsteht Chaos!).

Kategorien
Linkdump

JMeter – User’s Manual

JMeter – User’s Manual
Apache JMeter is a 100% pure Java desktop application designed to load test client/server software (such as a web application ). It may be used to test performance both on static and dynamic resources such as static files, Java Servlets, CGI scripts, Java objects, databases , FTP servers , and more. JMeter can be used to simulate a heavy load on a server, network or object to test its strength or to analyze overall performance under different load types.
aus Delicious/steinhobelgruen

Kategorien
Blog

Hotlinking revisited

Vor einiger Zeit hatte ich viele „Bilderdiebe“ hier, die meine Bilder in irgendwelchen Foren und Datingseiten und so Zeug per HTML-Tag direkt einfügten. Eigentlich habe ich genug Übertragungskapazität dafür, aber wenn jemand meine Bilder benutzt, dann möchte ich doch wenigstens genannt werden. Ich wies daher meinen Apache an, Bilder bei fremdem Referrer immer durch dieses Bild (bzw. Vorgänger dieses Bilds) zu ersetzen:

Bilderklau ist nicht nett.

Diese Maßnahme trifft aber neben den beabsichtigen Opfern auch nette Leute, die dieses Blog mit einem Feedreader lesen (insbesondere dann, wenn der Reader Webbasiert ist). Ich habe deshalb immer mal wieder Ausnahmen von der Regel konfiguriert, damit z.B. die Benutzer des Google-Readers (oder Netvibes, oder…) die Bilder in den Artikeln sehen können. Diese Liste kann aber unmöglich jemals vollständig sein (allein schon, weil sich ja jeder unter praktisch jeder Adresse z.B. Gregarius installieren kann), und gerade erst heute wurde ich in einem Kommentar gefragt, ob ich denn Alesti nicht mögen würde (dabei kenne ich Alesti nichtmal!). Schluss damit! Ab jetzt werden die Bilder bei Fremdverlinkung durch eine Version mit einem wazong-Logo-Karomuster als „Wasserzeichen“ drauf ersetzt. Das ist ein netter Kompromiss zwischen den beiden Extremen:

Wasserzeichen

Will jemand wissen, wie sowas geht?

Kategorien
Blog

no-www.

Das „www.“ in www.wazong.de ist eigentlich seit dem Umzug zu Hetzner gelogen. Es handelt sich nämlich nicht um eine große Organisation mit einem großen Netzwerk, in dem einem der vielen Server der Aliasname „www“ gegeben wurde, damit die Surfer ihn leichter finden kann (denn wer soll sich merken, daß IBM z.B. seine Webseite etwa auf einem Server namens „server53“ lagert, Sun aber z.B. auf einem Server namens „helios“). Die Apachekonfiguration war jetzt schon lange so eingestellt, daß unter wazong.de/… dieselben Inhalte ausgeliefert wurden wie unter www.wazong.de/…, aber das wars bisher auch.

Jetzt hat Gerrit van Aaken auf die Aktion (oder Organisation?) www. is deprecated hingewiesen, auf deren Seite ich ein sehr vernünftiges Argument fand:

[…]

Why then do many servers require their websites to communicate through the www subdomain? Mail servers do not require you to send emails to recipient@mail.domain.com. Likewise, web servers should allow access to their pages though the main domain unless a particular subdomain is required.

Das hat mich dazu veranlaßt, es www.praegnanz.de gleichzutun und den Servernamen(/alias) zwangsweise aus den URLs zu entfernen.

Kategorien
Blog

Hotlink

Wegen der stark ansteigenden Neigung, meine Bilder in irgendwelchen Foren einfach einzubinden, habe ich jetzt Maßnahmen ergriffen (naja, eigentlich nur eine):

Dieses Stück Apache-Magie ersetzt die Bilder, wenn der Referrer von „außen“ kommt:

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://((charon|www)\.)?wazong.de(/)?.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://images\.google\..*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://213\.239\.206\.203(/)?.*$ [NC]
RewriteRule .*\.(gif|jpg|jpeg|bmp)$ https://wazong.de/images/logo-big.png [R,NC]

Jeder darf meine Bilder jederzeit unter Nennung der Herkunft für nichtkommerzielle Zwecke nutzen, soll sie sich dafür aber bitte kopieren. Danke.