Skip to content

suexec my php, baby^wapache2

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.

Trackbacks

Zugschlusbeobachtungen on : suexec, die nächste

Show preview
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.\n\nDie Umstellung des Zielsystems von apache auf apache2 ging erschrec

Zugschlusbeobachtungen on : suphp

Show preview
Schon bei den Vorarbeiten zu diesem und diesem Artikel hat man mir sehr nahegelegt, suphp anzugucken. Das habe ich heute getan.\n\nSuphp kommt als Apache-Modul in der Debian-Package libapache2-mod-suphp daher. In Sarge ist eine 0.5-Version; in sid eine 0.6.

Zugschlusbeobachtungen on : fastcgi

Show preview
In Fortsetzung der Artikelreihe zur Entfernung von PHP-Scripts aus dem Accountkontext des Webservers ist heute FastCGI? an der Reihe.\n\nKurzzusammenfassung aus der Theorie: Es ist vermutlich performanter als suexec und suphp, bringt aber weder Erleichterun

Zugschlusbeobachtungen on : Trennung von Webapplikationen mit Extrainstanzen des Apache

Show preview
Die Artikelreihe zum Thema “Trennung von Webanwendungen untereinander”, die mit fastcgi, suphp und zwei Artikeln über das klassische suexec begann, findet heute ihren\nvorläufigen Abschluss mit dem Setup, für das ich mich letztendlich ents

Svens Netzblog on : Sicherer Webserver

Show preview
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

Comments

Display comments as Linear | Threaded

kju on :

Ich empfehle nach wie vor lighttpd. Dort wird PHP über FastCGI ausgeführt, so daß sowohl chroot wie setuid kein Problem sind. Und deutlich performanter als Apache(2)+modphp ist es auch noch.

Marc 'Zugschlus' Haber on :

lighttpd ist ein Exot. Den kann und will ich mir erst angucken, wenn ich apache (das ist der Standard) gut genug kann um vergleichen zu können.

In der Praxis wird man in einer Unternehmensanwendung mit einem Kunden, der IIS, IIS und IIS kennt, höchstens mit der Standardlösung der "freien" Welt kommen können, und das ist nun mal der apache.

Ich kann es nicht oft genug sagen: Es geht hier zu 80 % ums Lernen und zu 20 % darum, eine funktionierende Lösung zu erreichen.

Florian Laws on :

Auf der ApacheCon war über mpm_perchild auch zu hören, dass es keine Planung gebe, wann dieses Modul einsatzfähig werde. Anscheinend ist das gerade völlig ungewartet.

Django on :

Unter

http://www.debianhowto.de/de:howtos:sarge:apache2_php-fcgi

gibts ne Anleitung, wie man das noch mit Fastcgi macht. Das hat zudem noch den Vorteil, dass Suexec ein kleines Shell Script ausführt, man also nicht jedem User ein eigenes PHP Binary geben muss. Wenn PHP als CGI ausgeführt wird, dann werden nicht alle http Befehle übergeben, somit lässt sich kein WEBDAV machen. Interessant an dieser Lösung ist auch, dass man jedem User seine eigene Konfiguration und seine eigene PHP Version geben kann.

Add Comment

Markdown format allowed
Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.
Form options