Von einem der auszog, seine PHP-Scripts nicht mehr als www-data laufen zu sehen.
Auf der Suche nach einer Lösung für ein Standardproblem
Während meiner ISP-Zeit habe ich es nur in zwei Bereichen geschafft, den Rat eines Kollegen (“Du kannst Dich
nicht mit allem auskennen”) zu beherzigen: Webserver und RADIUS. Der bewusste Verzicht auf RADIUS-Kenntnisse wäre
heute im ISP-Bereich ein Hindernis, und Webserver-Knowhow versuche ich derzeit durch kleinere private Projektchen
aufzubauen.
Eins dieser Projektchen war der Bau eines Webservers, bei dem PHP-Scripts nicht mit den Rechten des Webservers
laufen, sondern mit den Rechten des Benutzers. Auf Servern, bei denen die Betreiber der virtuellen Server sich nicht
gegenseitig vertrauen, ist das eine Grundanforderung, die gar nicht sooo leicht zu befriedigen ist. Apache bringt
zwar schon seit geraumer Zeit suexec mit, das eigentlich genau diese Aufgabe erledigen soll. Allerdings arbeiten die
großen Hoster teilweise aus historischen Gründen mit grotesk gepatschtem suexec, so dass man die Berichte, die man aus
diesen Ecken bekommt, für ein privates Feldwaldundwiesenprojekt nicht umsetzbar sind. Die im Web ergooglebaren
Dokumentationen sind allesamt durchwachsen, und nicht selten so voller Widersprüche, dass man am besten mit dem Lesen
aufhört, ehe man völlig verwirrt ist.
Kurze Recherche zeigt, dass suexec sowieso ein Auslaufmodell ist. Irgendwann wird apache2 mit dem perchild threaded
model so weit sein, dass für jeden virtuellen Host ein eigener Apache-Prozess mit den entsprechenden Rechten läuft,
was alle heuten Probleme lösen dürfte. Aber, “This MPM is not currently expected to work correctly, if at
all.” Also lieber erstmal die Finger weg. Den Spezialfall PHP bekommt man heute mit suphp erschlagen, aber das ist
ein Projekt für die nächsten Tage. Mein aktuelles Vorhaben war, die Geschichte von der Pike auf zu lernen, und das
heißt definitiv klassisches suexec.
suexec ist ein Wrapper für CGI-Scripts, der vom Apache aufgerufen dank suid root erstmal seine Privilegien
eskaliert, nach Prüfung einer ganzen Latte von Preconditions seine Rechte auf die des “target users”
reduziert und schließlich endlich das CGI-Script aufruft. Nun, wenn ich hier von CGI spreche, meine ich auch CGI. Da
perl und php normalerweise als Apache-Modul gerufen werden, kann man da nicht mit suexec eingreifen. Also muss man die
Scripts als CGI aufrufen, was zu einem Performanceverlust führt. Das machen die großen Hoster auch nicht anders, also
ist dieser Weg so verkehrt nicht.
Also: mod_php raus, php4-cgi installiert und die (einfache) Konfiguration für “PHP als CGI”
durchgeführt.
Dabei fällt schon auf, dass die apache2-Packages von Debian ziemlich schlau gebaut sind: Jede Apache-Erweiterung
bringt in ihrer Package entsprechende Konfigschnipsel mit, die der Administrator mit den Scripts a2{en|dis}{mod|site}
ein- und ausschalten kann. Gute Arbeit, das fühlt sich viel besser an als die wilden Debconf-Orgien
(“Pondering....... Doing Magic......”) der apache-1.3-Packages. Ist halt wieder eine typische
Debian-Geschichte mit vielen kleinen Dateien, die apache aber dank seines flexiblen Konfig-Parsers automatisch
zusammenstellen kann; update-apache2.conf gibt es - glücklicherweise - nicht. Kris wird dieses Setup sicher nicht
gefallen, ich mag es. Schön finde ich auch, dass suexec, das sehr stark zur compilezeit konfiguriert wird, in der
Debian-Package sinnvoll parametriert daherkommt.
Die CGIs im Userdir ~/public_html laufen auf Anhieb unter meinem User. Allerdings ist’s etwas komplexer, das
auch ausserhalb des Userdirs hinzubekommen. Ursache dafür ist, dass ich mir selbst ein Bein gestellt hatte. Ich ging
fälschlicherweise davon aus, dass auch ausserhalb des Userdirs suexec seine Rechte auf die des Users fallen lässt, dem
die Datei gehört, in dem das CGI-Script steht; sozusagen ein auf den Webserver übertragenes suid-bit. Das stimmt aber
nicht: Für suexec ausserhalb des Userdirs muss man innerhalb der Definition des virtual hosts explizit mit der
Direktive SuexecUserGroup einen Target-User und eine Target-Group angeben, sonst fällt suexec transparent und
kommentarlos auf den Fallbackuser zurück, der www-data heißt und man somit der Meinung ist, dass das suexec gar nicht
aufgerufen würde. Nachdem dies endlich verstanden war, war der Weg zum ersten als mh laufenden CGI aus /var/www nicht
mehr weit.
PHP als CGI unter suexec ist ein bisschen schwieriger. Bei einem über eine Action aufgerufenen php zählt nicht der
Ablageort des PHP-Scripts, sondern der Ablageort des PHP-Binaries - und das liegt natürlich bei Debian weder innerhalb
des Webspaces, noch gehört es dem richtigen User. Also wird man für jeden User, der PHP verwenden wird, ein eigenes
PHP-Binary innerhalb des Webspaces brauchen, das obendrein auch noch dem richtigen User gehören muss. Ausserdem
braucht’s wohl noch eine passende Action-Direktive für jeden Virtuellen Host; das hab ich allerdings noch nicht
ausprobiert, weil ich immer nur mit einem virtuellen Host gearbeitet habe. Kaum macht man’s richtig,
funktioniert’s auch schon, und mein passthru(“id”) sagte ordentlich id=1001(mh). Erfolgserlebnis.
Was lernen wir daraus: Auch wenn man erwartet, zu wissen was in der Doku steht, kostet Querlesen gerne mal einen Tag
Zeit, weil man die wichtigen Informationen mehrfach überliest. de.comm.software.webserver ist für Fragen dieser
Gewichtsklasse überfordert, ausser Bastian Blank hat sich niemand zur Antwort auf meine Fragen motivieren
können.
Dasselbe gilt für #apache in Freenode, dessen Niveau bedauernswert niedrig ist und wo die Leute größtenteils nicht
einmal wussten, was suexec ist. Das beste Debugging-Tool ist nach wie vor strace, weil man damit dem Prozess so weit auf
die Finger gucken kann, dass man irgendwann mal zu dem Schluß kommt “das ist aber nicht so wie ichs aus der Doku
erinnere, lasst mal lieber genau nachlesen”.
Nächste Projekte: suphp, und dann endlich die erste eigene s9y-Testinstallation.
In Fortsetzung von suexec my php, baby^wapache habe ich gestern suexec auf dem ersten Produktivsystem verfügbar gemacht, und einige Unzulänglichkeiten im Debian-Setup gefunden. Die Umstellung des Zielsystems von apache auf apache2 ging erschrec Comments (4)
Tracked: Nov 27, 16:07
Schon bei den Vorarbeiten zu diesem und diesem Artikel hat man mir sehr nahegelegt, suphp anzugucken. Das habe ich heute getan. Suphp kommt als Apache-Modul in der Debian-Package libapache2-mod-suphp daher. In Sarge ist eine 0.5-Version; in sid eine 0.6. Comments (4)
Tracked: Dec 11, 22:22
In Fortsetzung der Artikelreihe zur Entfernung von PHP-Scripts aus dem Accountkontext des Webservers ist heute FastCGI? an der Reihe. Kurzzusammenfassung aus der Theorie: Es ist vermutlich performanter als suexec und suphp, bringt aber weder Erleichterun Comments (4)
Tracked: Dec 30, 15:22
Die Artikelreihe zum Thema “Trennung von Webanwendungen untereinander”, die mit fastcgi, suphp und zwei Artikeln über das klassische suexec begann, findet heute ihren vorläufigen Abschluss mit dem Setup, für das ich mich letztendlich ents Comments (4)
Tracked: Feb 18, 17:22
Das es nicht einfach ist, einen Webserver zu bauen, der mit potentiell "feindlichen" Scripten und Programmen beladen werden wird (lies: Webserver für Studenten und Mitarbeiter), was mir ja schon von Anfang an bewusst.Aber die Arbeit, die ich bis Comment (1)
Tracked: Sep 04, 22:53