Aus Linux-Magazin 08/2007

Skripte mit Apache sicher ausführen

© photocase.com, rotwild

Wichtiger als die Performance von Webanwendungen ist den meisten Admins deren Sicherheit. Bei Webservern mit mehreren Benutzern hilft das Suexec-Modul, von allen schreibbare Verzeichnisse zu vermeiden.

Wer einschlägige Mailinglisten verfolgt, findet den schlechten Ruf von Webanwendungen als Security-Albtraum bestätigt. Woran das liegt, darüber streiten die Experten. Bringt die verteilte Struktur von Webanwendungen mit zustandslosem Protokoll und allerhand Klimmzügen die Sicherheitsprobleme schon mit sich, liegt es an Programmiersprachen wie PHP oder sind Webprogrammierer einfach nur schlecht ausgebildet? Was auch immer die Ursache ist, fest steht, dass es so nicht bleiben kann.

Ein ganzheitlicher Ansatz, der von Grund auf alle Komponenten vom Betriebssystem über den Webserver bis zur Programmiersprache neu entwirft, ist nicht zu erwarten. Stattdessen arbeiten die Protagonisten der Web-Evolution an der Verbesserung einzelner Komponenten, was nach allgemein verbreiteter Meinung zwar nicht die beste Lösung ist, aber immer noch besser als nichts.

Nicht gut: Jeder darf alles

Wer fertige Pakete für Onlineforen oder Ähnliches installiert, findet in der Installationsanleitung häufig einen Absatz, der zur Einrichtung eines für alle beschreibbaren (world-writable) Verzeichnisses auffordert – nicht unbedingt das, was man sich unter einer sicheren Konfiguration vorstellt. Der Grund dafür ist unter anderem, dass der Webserver mit einer anderen Benutzer-ID läuft als jener, der die entsprechenden Verzeichnisse gehören. Umso schlimmer, wenn sich mehrere User einen Server teilen. Ob sie nun Verzeichnisse für alle oder nur die Webserver-UID beschreibbar machen, das Ergebnis bleibt gleich: Jeder kann in die Verzeichnisse jedes anderen schreiben. Da ist er wieder, der Albtraum.

Einen Auswege aus dem Dilemma bietet das Apache-Modul Suexec. Gemäß recht restriktiven Vorgaben führt es CGI-Skripte unter konfigurierbaren Benutzer-IDs aus. Im Gegensatz zu früheren Zeiten lässt sich das Suexec-Modul mit Apache 2 relativ leicht verwenden [1]. Die meisten Linux-Distributionen liefern es mit dem Apache-Paket aus.

Bei Fedora beispielsweise enthält das Paket »httpd« die Moduldatei »mod_suexec.so« und den Wrapper »/usr/sbin/suexec«. In Debian Etch heißt das entsprechende Paket »apache2«. Der Apache-Server verrät, aufgerufen mit der Option »-V«, ob er Suexec unterstützt:

$ /usr/sbin/httpd -V | grep -i suexec -D SUEXEC_BIN="/usr/sbin/suexec"

Um die gewünschte Sicherheit zu gewährleisten, hat das Suexec-Programm einige relevante Werte fest einkompiliert, unter anderem die Logdatei, Pfade für ausführbare Dateien, das Web-Wurzelverzeichnis (Document Root) und eben Benutzer- und Gruppen-ID. Auch Suexec verrät seine Konfiguration über eine Kommandozeilenoption, analog zu Apache. Listing 1 zeigt die Einstellungen unter Debian Etch.

Listing 1: »suexec
-V«

01 # /usr/lib/apache2/suexec -V
02  -D AP_DOC_ROOT="/var/www"
03  -D AP_GID_MIN=100
04  -D AP_HTTPD_USER="www-data"
05  -D AP_LOG_EXEC="/var/log/apache2/suexec.log"
06  -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
07  -D AP_UID_MIN=100
08  -D AP_USERDIR_SUFFIX="public_html"

Die Variable »AP_DOC_ROOT« legt das Verzeichnis fest, unterhalb dessen sich die Skripte der Benutzer befinden müssen. »AP_SAFE_PATH« bestimmt den Pfad der ausführbaren Programme, den die Skripte übergeben bekommen. Entsprechend muss die Apache-Konfiguration aussehen. Hier soll »/var/www« mehrere Unterverzeichnisse enthalten, die jeweils einem Benutzer gehören.

Die Zeilen 6 bis 8 von Listing 2 setzen in der Apache-Konfiguration die nötigen Ausführungsrechte für das Verzeichnis des Benutzers »beispiel«, das von Zeile 3 als sein Wurzelverzeichnis festgelegt wird. Zeile 10 weist Dateien mit der Endung ».cgi« als CGI-Skripte aus. Sind das Suexec-Modul geladen und der Wrapper verfügbar, genügt Zeile 4 mit der Direktive »SuexecUserGroup«.

Listing 2:
»suexec.conf«

01 <VirtualHost *>
02    ServerName beispiel.example.com
03    DocumentRoot /var/www/beispiel/
04    SuexecUserGroup beispiel beispiel
05 
06    <Directory /var/www/beispiel>
07       Options +ExecCGI
08    </Directory>
09 
10    AddHandler cgi-script .cgi
11 </VirtualHost>

Wer nun im Verzeichnis »/var/www/beispiel« ein CGI-Skript ablegt, wird vermutlich eine böse Überraschung erleben, nämlich einen Internal Server Error oder auch einfach eine leere Seite. Ein Blick in die Suexec-Logdatei (bei Fedora »/var/log/httpd/suexec.log«) verrät Näheres:

target uid/gid (501/501) mismatch with directory (501/501) or program (500/501)

Aus Sicherheitsgründen besteht Suexec darauf, dass die Verzeichnisse und die ausführbaren Dateien auch dem Benutzer gehören, der in der Apache-Konfiguration aufgeführt ist. Stimmen die Eigentumsverhältnisse und Rechte, zeigt das folgende kleine CGI-Shellskript das gewünschte Ergebnis (Abbildung 1).

#!/bin/sh
echo "Content-type: text/html"
echo
echo "UID/GID:" `id`

Nun will vermutlich nicht jeder Webseiten-Betreiber sich aus Sicherheitsgründen wieder der CGI-Technologie aus dem letzten Jahrhundert verschreiben, die verglichen mit der modernen In-Process-Verarbeitung recht langsam ist.

Abbildung 1: Der Browser bringt es an den Tag: Das CGI-Skript läuft mit der über Suexec eingestellten User- und Gruppen-ID.

Abbildung 1: Der Browser bringt es an den Tag: Das CGI-Skript läuft mit der über Suexec eingestellten User- und Gruppen-ID.

Trotzdem schnell

Als Alternative zum alten CGI bietet es sich an, die Fast-CGI-Schnittstelle (FCGI) zu verwenden, mit der sich auch PHP-Skripte in die Suexec-Infrastruktur integrieren lassen. Das anscheinend von seinen Entwicklern aufgegebene Mod_fcgi wurde mittlerweile von dem weitgehend kompatiblen Mod_fcgid (das d am Ende beachten) abgelöst [2], das es ebenfalls für die meisten Distributionen als Binärmodul gibt.

Es muss passen

Die Hauptschwierigkeit bei der Integration der FCGI- und Suexec-Module liegt darin, die restriktiven Vorgaben der Module zur Deckung zu bringen. Findet als so genannter FCGI-Wrapper nämlich das systemweite PHP-Binary Verwendung, beschwert sich Suexec wieder, weil es außerhalb des Document Root liegt. Die Lösung besteht darin, in ein Verzeichnis unterhalb des jeweiligen Web-Wurzelverzeichnisses zu kopieren. Der entsprechende Abschnitt der Apache-Konfiguration sieht so aus:

AddHandler fcgid-script .php
FCGIWrapper /var/www/beispiel/bin/php-cgi.php

Vorausgesetzt sind hierbei eine ansonsten funktionierende FCGI-Installation (meist mit der Paketinstallation erledigt) und eine CGI-Version des PHP-Interpreters, die auch Fast CGI beherrscht. Das verrät ein Aufruf von »php-cgi -v«. Die darauf folgende Ausgabe muss das Kürzel »fcgi« enthalten.

Dem aufmerksamen Admin wird ein kleines Problem nicht entgangen sein: Der Webnutzer kann nun das PHP-Binary nach Wunsch austauschen. Wer etwa als Provider einen solchen Server betreibt, wird das aus Sicherheitsgründen eher zu vermeiden suchen. Wie also dem User das Ändern des PHP-Interpreters verbieten, wo doch Suexec verlangt, dass er alle Rechte daran besitzen soll?

Bitte nicht ändern

Die Lösung liegt im Immutable-Flag, das jede Änderung an einer Datei auch ihren Eigentümern verweigert. Folgender Befehl setzt das Flag für den PHP-Interpreter des Benutzers »beispiel«:

chattr +i /var/www/beispiel/bin/php-cgi

Mit dieser Änderung funktioniert das Suexec/FCGI-Setup wie gewünscht, allerdings nur auf Ext-2/3-, XFS, JFS- und Reiser-Dateisystemen, die Attribute wie das Immutable-Flag beherrschen. Abbildung 2 zeigt den Ablauf und das Ergebnis noch einmal im Detail.

Abbildung 2: Setzt der Server-Administrator das Immutable-Flag des PHP-Interpreters, kann auch der Eigentümer die Datei nicht mehr verändern.

Abbildung 2: Setzt der Server-Administrator das Immutable-Flag des PHP-Interpreters, kann auch der Eigentümer die Datei nicht mehr verändern.

Über diesen, zugegebenermaßen nicht ganz einfachen Weg laufen auch PHP-Skripte vom Suexec kontrolliert mit den einfachen Rechten ihres Benutzers. Zumindest ein gewisser Fortschritt bei der Absicherung eines Webservers, der die Sites von mehreren Benutzern hostet. Dank der Flexibilität der FCGI-Schnittstelle lassen sich auf diese Weise auch Skripte mit anderen Programmiersprachen absichern, zum Beispiel auch Ruby on Rails. Eingefleischte PHP-Anwender finden in Suphp [3] eine Alternative zu der hier beschriebenen Lösung.

Infos

[1] Apache Suexec: [http://httpd.apache.org/docs/2.0/suexec.html]

[2] Mod_fcgid: [http://fastcgi.coremail.cn]

[3] Suphp: [http://www.suphp.org]

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 2 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben