Sichere Passwörter nerven, die kann eh sich niemand merken!
Man kennt es: Die Joomla!-Seite ist bereit für den Onlinegang und man macht sich letzte Gedanken über die Sicherheit.
- Backupkonzept steht
- Berechtigungen sind eingestellt
- Das Updateplugin wurde konfiguriert
Nun soll doch noch das Administrator-Verzeichnis der Joomla!-Installation per .htaccess geschützt werden. Im Regelfall ist das ein zusätzlicher Passwortschutz. Noch ein Passwort? Man hört schon direkt die wehklagenden Seufzer der Redaktion. Doch es geht auch ohne!
Vorgeplänkel - warum nicht einfach ein Passwortschutz?
Prinzipiell geht es beim Schutz des Administrator-Verzeichnisses von Joomla! darum, Brute Force Attacken zu erschweren und das Ausnutzen von potenziellen (Backend)Sicherheitslücke zu unterbinden.
Gleichzeitig müssen Redakteure täglich mit dem Backend interagieren und sich bei einem Passwortschutz nicht nur ihr eigenes Passwort für den Backendlogin merken sondern nun auch noch ein zusätzliches Passwort für die htaccess. Bei komplexeren Passwörtern landen diese gerne mal auf Post-Its, die dann offen einsehbar sind.
Zusätzlich gibt es oft auch eine gewisse Fluktuation innerhalb größerer Redaktionsteams und man muss entweder regelmäßig das Passwort der .htaccess anpassen oder für jeden Redakteur einen Eintrag in der Passwortdatei anlegen. Oft muss dafür dann ein Techniker/System-Administrator gerufen werden.
Die Ausgangslage
Recht grob kann man Hackversuche in zwei Kategorien einteilen:
- gezielte Angriffe
-
Ein Hacker nimmt gezielt die Homepage ins Visier, analysiert ihre Schwachstellen und fährt dann den Angriff.
Im Regelfall ist es ohne tieferes Know-How sehr schwer, diese Angriffe abzuwehren. Wahrscheinlich bringt hier auch ein Passwortschutz relativ wenig. Deshalb werden wir uns hier mit diesem Szenario nicht beschäftigen. - willkürliche Angriffe
- In diesem Szenario werden willkürlich Joomla!-Seiten nach bekannten Sicherheitslücken abgeklopft. Meist geschieht das automatisiert über ein Script. Es wird nach dem Gießkannenprinzip gearbeitet. Im Regelfall sind das standardisierte Angriffsmuster ohne "Intelligenz". Um diese geht es in diesem Beitrag; es ist auch ohne Passwortschutz im Backend machbar, die Seite davor zu schützen.
Somit brauchen wir eine Lösung, die einfach Anfragen an das Backend abblockt, wenn der User sich vorher nicht verifiziert hat, aber gleichzeitig soll diese Verifizierung im Hintergrund geschehen, ohne dass der User z.B. ein Passwort eingeben muss.
Die Idee
Das Prinzip ist ganz einfach: wir erlauben nur Nutzern den Zugriff auf das Backend, die über einen speziellen Link kommen. Aber im Gegensatz zu diversen Plugins, die (indem man einen Hash an die URL hängen muss) auf Systemebene arbeiten, lagern wir das ganze eine Ebene höher an: in der htaccess.
Kommt ein Benutzer über den speziellen Link, wird ein Cookie gesetzt. Dieses validieren wir dann in der htaccess, die das Backend absperrt..
Konkret: der Nutzer geht z.B. auf die URL www.example.com/jadmin und wird dann im Hintergrund für das Backend freigegeben und zur Administration weitergeleitet.
Umsetzung in der Praxis
Wie sieht das ganze nun in der Praxis aus? Zu allererst benötigen wir einen Ordner jadmin. Dieser Ordner ist der Einstiegspunkt, bzw. der Link, der das Backend freischaltet. Hier kann man variieren und jeden beliebigen Namen nehmen.
In diesen Ordner wird nun eine index.php gelegt, die das Cookie setzen und eine Weiterleitung vornehmen soll:
<?php // Cookiename + Wert, die in der htaccess getestet werden sollen // Können angepasst werden $cookiename = 'accesscookie'; $cookievalue = 'accessallowed'; setcookie($cookiename, $cookievalue, 0, '/'); // Setze das Scheme, wenn vom Server nicht gegeben (http(s)) if (!isset($_SERVER['REQUEST_SCHEME'])) { $_SERVER['REQUEST_SCHEME'] = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http'; } // http(s):// $url = $_SERVER['REQUEST_SCHEME'] . '://'; // Domain $url .= $_SERVER['SERVER_NAME']; // eventuell Unterordner + "administrator" $url .= rtrim(dirname(dirname($_SERVER['SCRIPT_NAME'])), '/') . '/administrator'; // Weiterleitung header('Location: ' . $url);
Im nächsten Schritt muss nun eine .htaccess angelegt werden, die zum einen das Backend absperrt aber Nutzer mit gesetzem Cookie durchlässt. Diese .htaccess muss in den Ordner administrator gelegt werden.
RewriteEngine On RewriteCond %{HTTP_COOKIE} !accesscookie=accessallowed [NC] RewriteRule .* - [R=404,NC,L]
Das war es schon!
Wenn nun das Backend aufgerufen (www.example.com/administrator) wird, sollte eine "404 - not found" Fehlermeldung erscheinen. Wird nun aber www.example.com/jadmin aufgerufen, landet man auf der Loginmaske des Backend.
Danach kann ganz normal der reguläre Link (www.example.com/administrator) genutzt werden.
Die Vorteile sind offensichtlich:
- das Backend ist abgesperrt, ohne dass ein weiteres Passwort gemerkt werden muss.
- Gleichzeitig passiert die Validierung nicht im System selbst sondern schon im Schritt zuvor.
- Last but not least kann der Ordner ohne großen Aufwand umbenannt werden, sodass recht schnell der Zugang geändert werden kann.
Verbesserungen sind möglich:
Eine Verbesserung wäre es, wenn der "geheime" Link, der das Backend freischaltet, im Backend selbst pflegbar bzw. änderbar ist. Hierzu bietet sich die Umleitungskomponente von Joomla! an.
Die Umleitungskomponente erlaubt es, nicht existierende Seiten (die ein 404-Fehler verursachen) auf eine beliebige URL zu leiten. Das machen wir uns direkt zu nutzen.
Damit die Umleitungskomponente funktioniert, muss das Plugin aktiviert werden. Der Name lautet "System - Umleitung".
Zuerst muss die index.php angepasst werden, sodass der Zugriff auf eine URL, definiert in der Umleitungskomponente beschränkt wird:
<?php $backendcode = 'UqaygwDwzHZ4'; if (!isset($_GET['code']) || $_GET['code'] != $backendcode) { exit; } // Cookiename + Wert, die in der htaccess getestet werden sollen // Können angepasst werden $cookiename = 'accesscookie'; $cookievalue = 'accessallowed'; setcookie($cookiename, $cookievalue, 0, '/'); // Setze das Scheme, wenn vom Server nicht gegeben (http(s)) if (!isset($_SERVER['REQUEST_SCHEME'])) { $_SERVER['REQUEST_SCHEME'] = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http'; } // http(s):// $url = $_SERVER['REQUEST_SCHEME'] . '://'; // Domain $url .= $_SERVER['SERVER_NAME']; // eventuell Unterordner + "administrator" $url .= rtrim(dirname(dirname($_SERVER['SCRIPT_NAME'])), '/') . '/administrator'; // Weiterleitung header('Location: ' . $url);
Und nun erstellen wir eine neue Umleitungsregel in der Umleitungskomponente:
Ab sofort ist das Backend über den Link www.example.com/mein-geheimer-link erreichbar. Somit kann relativ flexibel und zu jederzeit im Backend der Zugriffslink geändert werden.