500 – Internal Server Error

Man sieht den „500 – Internal Server Error“ gerne mal bei Server-Arbeiten: Updates, Umzug, Backup zurückspielen etc. Es sollte Alles so sein wie immer – tut es aber nicht. Statt der erhofften Webpräsenz glänzt dieser Allgemeinposten.

Aufgrund der hohen Verbreitung von WordPress werden viel WordPress-Anwender nach den Ursachen suchen, im Kern deutet diese Meldung aber auf ein Problem auf der darunterliegenden Ebene. Genauer: hier schimpft der Server Apache – sinngemäß steht die Meldung für etwas wie: „was immer ich ausgeben soll, ich komme nicht ran.“

Maßnahme 1: in Apache Error-Log einschalten.

Für den 500er gibt es einige Auslöser. Es hilft dabei natürlich ungemein, wenn man nachlesen kann, worüber der Server meckert. Der Apache-Server kann dabei so eingestellt werden, dass Fehler zu einer kurzen Notiz in der Fehlerlog-Datei führen, im Standard heißt die Datei error_log und liegt in einem Ordner namens log, auf der selben Ebene wie der vom Server zu publizierende Ordner html.

Fehler

In der Log-Datei steht dann z.B. so etwas wie folgt:

[warn] UID of script "/home/www/webXY/html/index.php" is smaller than min_uid

Hier springt das Modul suPHP an. Darin sind u.a. aus Sicherheitsgründen bestimmte Plausibilitäten aktivierbar. Hier geht es darum, dass die zu einem Account hinterlegte Nummer nicht in der erwarteten Größenordnung ist. Konkret geht es um das unter Windows verbreitete Bequemlichkeitsphänomen, einfach Alles als angemeldeter Administrator zu machen – dann klappt Alles und es gibt wenig Gemecker. So schön das kurzfristig sein mag: aus Sicherheitsgründen soll Vieles oft gar nicht gehen oder eben nur, wenn bestimmte Voraussetzungen wirklich erfüllt sind. Im Falle eines geglückten Einbruchs in den Webserver sollte z.B. eben noch längst kein Root-Zugriff auf den Server-Rechner und ggf. darauf laufende hunderte weitere Dienste möglich sein.

Hintergrund

Bei den Linuxen/Unixen ist es so, dass die Accounts mit einer Nummer – einer Art Zähler – assoziiert sind. So hat z.B. der Standard-Account root die ID 0 und der technische Account www-data (Debian) die ID 33 – heute in den Distributionen meist schon vorkonfiguriert. Einfache neu angelegte Accounts haben hingegen 4-stellige IDs. Bei Suse und Redhat heißt der Apache-User hingen www-run.

Eine in suPHP einstellbare Regel prüft nun, ob eine Eigentümer- oder Gruppen-ID größer als ein bestimmter Mindestwert ist. Es wird also getestet, ob auch die Dateien einem einfachen User gehören oder ob der Eigentümer ein technischer Account ist, bei dessen Veruntreuung dann gleich recht viel den Bach runterginge.

Keine gute Lösung: in der Datei suphp.conf die Werte für min_uid und min_gid auf 0 setzen. Das wäre weniger das System sicher zum Laufen zu bringen sondern eher das Schloss aus der Wohnungstür ausbauen. Wie zuhause: eine Tür sollte schon mit Schloss funktionieren.

Maßnahme 2: Eigentümer-Verhältnisse prüfen/ggf. korrigieren

Dateien unter Linuxen/Unixen haben zwei Eigentümer-Verhältnisse: sie gehören direkt einem Account und sie gehören zusätzlich zu einer Gruppe. Beide Werte können separat gesetzt werden. Die Anforderung hier ist per default, dass sowohl der User-Account wie der hinterlegte Gruppen-Account eine ID größer hundert haben.

Dieser Fehler kommt meist schlicht daher, dass man sich als root per SSH/SCP o.ä. einloggt, im Dateisystem Dateien hin- und herkopiert und diese damit eben root (… mit ID=0, siehe oben … ) gehören.

Lösung: die Dateien und Ordner unterhalb des publizierten html-Ordners müssen einfachen Usern gehören – bei Debian/Confixx-Installationen schlichtweg den Usern web1, web2 etc.

Ein Kommandozeilencheck für den Server geht so:

su - www-data -s /bin/bash -c "cd /var/www/webXY/html"

Als Ausgabe gibt es eine Meldung, ob der Zugriff möglich ist oder nicht. Wenn der Apache-Account www-data nicht an den html-Ordner kommt, ist zumindest eine Ursache schon mal gefunden.

Fehler-Möglichkeit 2

Eine weiteres Fehlerbild im Log-File sieht so aus:

[crit]
(13)Permission denied: /var/www/webXY/html/.htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable

Die aufgerufene Website zeigt dann einen Fehler wie folgt:

403 Forbidden
You don’t have permission to access / on this server.

Hier schlägt eine ähnliche Regel wie oben zu: Der Ober-Ordner, in dem das ganze webbasierte System (Blog, CMS, Wiki, Forum, Shop etc.) liegt, darf ebenfalls nicht irgendwem gehören. Hier gilt:

  • Eigentümer muss eine einfacher User sein, wie oben z,B, web1web2 etc.
  • Gruppe muss www-data sein 

Der Hinweis auf die Datei .htaccess in der Log-Datei kann an dieser Stelle also auch auf eine falsche Fährte führen.

Maßnahme 3: suPHP-Log unter /var/log/suphp prüfen – tauchen die letzten Aufrufe auf?

Ein typischer erfolgreicher Eintrag sieht so aus:

[Wed Feb 12 15:38:13 2014] [info] Executing „/var/www/webXY/html/something.php“ as UID 1001, GID 1001

Wenn es keinen Eintrag nach einem abgesetzten Aufruf gibt, dann liegt der Fehler noch vor dieser Ebene.

Fehler-Möglichkeit 4 – selbst ausgesperrt

Im Log-File steht so etwas:

[Sat May 23 16:31:23 2015] [error]
No such file or directory: Could not open password file: /var/www/SOMEUSER/html/.somepassfile

Tricky – zumal man (oder ein Admin … oder theoretisch auch ein Angreifer) hier selbst etwas verbaut hat. Hier liegt in einer .htaccess-Datei eine Steuerungsanweisung für den Apache-Server vor. In eine .htacess-Datei steht etwas in der Art:

# .htaccess-Border
<FilesMatch "(wp-*.php)">
    AuthName "HTAccess"
    AuthType Basic
    AuthUserFile /somepath/.somefile
    require valid-user
</FilesMatch>

Also:

  • Jemand hat die Zugangsdateien wie wp-login.php mit einer Server-seitigen Zugangssperre versehen (so eine Lösung, bei der eine von Apache erzeugte Dialogbox noch vor dem WordPress-Login aufpoppt) – die Passwort-Lösung aus alten HTML-Tagen
  • Diese Zugangslösung funktioniert so, dass in der .htaccess-Datei selbst oder in der hinter
      AuthUserFile

    genannten Datei eine Kombination aus UserID und Passwort gespeichert ist.

  • Der Fehler dabei: die benötigte Datei mit dem erwähnten Dateinamen existiert so nicht (Tippfehler beim Dateinamen oder Tippfehler im Pfad)

Lösungen:

  • den ganzen FilesMatch-Block löschen oder
  • die im FilesMatch-Block erwähnte Datei anlegen und eine gültige UserID- und Passwort-Kombination dort hinterlegen: dazu gibt es z.B. den Service htaccesstoolshttp://www.htaccesstools.com/htpasswd-generator/, da man im Jahr 2015 Passworte natürlich nicht einfach im Klartext in Dateien schreibt.

Weitere Fehler-Möglichkeiten

  • Ähnlich wie oben mit den Eigentümern: natürlich kann auch bei korrekt gesetzten Eigentümern die Einstellung der Rechte unpassend sein.
  • Beim Kopieren eines Alt-Systems ist möglicherweise eine .htaccess-Datei dabei, deren Einträge zum aktuellen Zustand des Neu-Systems nicht passen. Typischerweise spiegeln .htaccess-Dateien in einem gewissen Rahmen auch wieder, was die jeweilige Server-Version an Features bietet oder erfordert. Wie beim Umtopfen: nicht jede Orchidee kommt mit noch so neuer Palmenerde klar.