HowTo: https beim Anmelden an WordPress Blog Backend + Schutz gegen Brutforce

Bei meinem Blog hatte ich vor kurzem zwei Dinge die ich Aendern wollte:

  1. Der Blog soll ueber http:// lesbar sein, aber Anmelden soll grundsaetzlich immer https:// sein, damit das Passwort nicht unverschluesselt durch das Netz schwirrt
  2. Der Login Bereich soll gegen Brutforce Attacken abgesichert sein

Anmelden an Blog Backend nur ueber https://

Viele Menschen lesen diesen Blog oder finden hier hin. Ich bin immer wieder erstaunt darueber. Die Verbindung soll grundsaetzlich unverschluesselt sein, aber das Anmelden wollte ich – egal was ich eingebe – immer auf https:// landen, damit das Passwort nicht unverschluesselt durchs Netz uebertragen wird. Dafuer habe ich im vhost der auf Port 80 lauscht die folgende Rewrite Regel hinzugefuegt:

RewriteEngine On
RewriteCond %{REQUEST_URI}  ^/wp-login.php$
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^(.*)$ https://blog.pregos.info/wp-login.php/%1? [R=302,L]

So werde ich immer auf https weitergeleitet ohne das ich darauf achten muss, das was ich eingebe. Es ist wichig mit mod_rewrite zu arbeiten und nicht nur einen Alias zu setzen, da wenn man sich aus dem Backend abmeldet man dann auch auf den Anmeldebildschirm zurueckgeleitet wird. Da haengen GET Parameter dran. Ein Alias wuerde dann nicht mehr greifen, die mod_rewrite Regel oben tut es hingegen.

Schutz gegen ungewollte (Brutforce) Anmeldeversuche am Blog Backend

Nach vielen vielen Jahren den ich diesen Blog nun schon schreibe bin ich auf das Plugin WP fail2ban gestossen. Es loggt fehlgeschlagene Loginversuche ins Backend mit, so das man diese mit fail2ban auswerten und behandeln kann. Ich habe mit ein bisschen schlechten Gewissen das Plugin installiert und mal geschaut was so passiert. Von der Anzahl der Attacken war ich echt ueberrascht. Teilweise Skriptkiddies die ueber Stunden hinweg von der gleichen IP probieren, teilweise aber auch Brutforce Attacken mit ueber 16000 Loginversuchen in ~3h.

Spannend zu sehen was mir vorher alles entgangen ist, aber so richtig gut fuehlt sich das nicht an, dass von tausenden von Hosts probiert wird und die immer erst nach drei Versuchen gesperrt werden. Deswegen ist es am einfachsten, wenn man das Backend mit einem Benutzernamen und Passwort direkt im Apache sichert. Das habe ich auf die folgende Art und Weise im vHost getan:

<Location /wp-admin/>
        AuthName "Wordpress Login"
        AuthType Basic
        AuthUserFile /var/www/pregos.info/htpasswd-blog
        Require valid-user
</Location>

Da die Angreifer einfach per POST Daten an die wp-login.php schicken habe ich die Datei selbst auch noch explizit wie folgt abgesichert:

<FilesMatch "wp-login.php">
        AuthName "Wordpress Login"
        AuthType Basic
        AuthUserFile /var/www/pregos.info/htpasswd-blog
        require valid-user
</FilesMatch>

In wieweit das Passwort ein komplexes Zufallspasswort oder ein einfacher zu merkendes ist, ist jedem selbst ueberlassen. Es hilft aber erstaunlich einfach und effizient gegen die Attacken auf meinen Blog.

Neues SSL-Zertifikat und spdy Unterstuetzung

Ab heute hat mein Blog ein neues SSL-Zertifikat von CAcert.org. Wenn mich jemand „assuren“ wuerde, waere ich dem sehr dankbar.

Weiter ist mein Blog nun auch ueber spdy erreichbar. Ein deutlicher Geschwindigkeitszuwachs, um es mal einfach auszudruecken. Die Installation gestaltete sich sehr einfach: runterladen, installieren, Apache neu starten, fertig. Das Apache-Modul gibt es hier bei Google.

Um in den Genuss des schnelleren Seitenaufbaus zu kommen als Firefox-Nutzer unter about:config nach network.http.spdy.enabled suchen und auf true setzen.

HowTo: multiple Apache2 vhosts mit unterschiedlichen SSL-Zertifikaten

Die Aufgabe: in Apache bei verschiedenen vhosts verschiedene SSL-Zertifikate fuer die Verschluesselung definieren.
Das Problem: mit mod_ssl laesst sich das ganze nicht so einfach realisieren.
Die Ursache: vhosts basieren auf Basis von HTTP-Headers, SSL liegt ein Layer darunter. Die Verbindung wird gesichert bevor HTTP gesprochen wird. Der Server kann bei Verbindungsaufbau nicht wissen welchen vhost er danach bedienen soll, deswegen kann er das richtiger Zertifikat nicht auswaehlen.
Die Loesung: mod_gnutls
HowTo: das ganze unter Debian Lenny

Ich gehe an dieser Stelle davon aus, dass man bereits SSL-Zertifikate generiert hat (blubs).

Als naechstes ist es nun wichtig das Modul zu installieren, anzupassen und zu aktivieren:

aptitude install libapache2-mod-gnutls

Danach die /etc/apache2/mods-available/gnutls.conf anpassen:

<IfModule mod_gnutls.c>
  GnuTLSCache dbm /var/cache/apache2/gnutls_cache
 
  AddType application/x-x509-ca-cert .crt
  AddType application/x-pkcs7-crl    .crl
 
  GnuTLSCacheTimeout 300
  NameVirtualHost *:443
</IfModule>

und das Modul aktivieren:

a2enmod gnutls

Nun noch die Zeile:

Listen 443

zu der /etc/apache2/ports.conf hinzufuegen und dabei darauf achten, dass die Zeile vor der „Listen 80“ steht, da es sonst in der /var/log/apache2/error.log zu den folgenden Zeilen kommen kann:

[Sun Dec 05 14:37:06 2010] [error] [client ::1] GnuTLS: Handshake Failed (-8) 'A record packet with illegal version was received.'

Nun koennen die vhosts entsprechend eingerichtet werden. Hier ein generisches Beispiel fuer einen vhost:

<VirtualHost *:443>
    ServerAdmin webmaster@example.net
    ServerName www.example.net
    ServerAlias example.net
    DocumentRoot /var/www/example.net/
 
    <Directory /var/www/example.net/>
        Options +Indexes
    </Directory>
 
    GnuTLSEnable on
    GnuTLSCertificateFile /etc/ssl/myCA/private/www.example.net-key-cert.pem
    GnuTLSKeyFile /etc/ssl/myCA/private/www.example.net-key-cert.pem
    GnuTLSPriorities SECURE:!MD5
 
    CustomLog /var/log/apache2/example.net-access.log combined
</VirtualHost>

Nach einem Neustart von Apache2 kann nun per https auf den gewuenschten vhost zugegriffen werden, viel Spass beim Einrichten des zweiten und freien wenns klappt!