mod_php und Apache als User 'nobody'
AlexBausW
- webserver
0 Sönke Tesch
Hallo
Auf einem Suse 7.3 Linux-Rechner läuft ein frischkompilierter Apache 1.3.26 mit PHP 4.2.1 als Modul. mod_php wurde noch unter Apache 1.3.22 kompiliert, was aber angeblich keine Problem bereiten soll und eigentlich auch nicht tut, außer daß mit phpinfo() in der Sektion "apache" noch die alte Version gemeldet wird:
APACHE_INCLUDE
APACHE_TARGET
Apache Version Apache/1.3.22
Apache Release 10322100
Apache API Version 19990320
Hostname:Port dynamicwebdevelopment.de:80
User/Group nobody(65534)/101
.
.
.
safe_mode ist on.
Der Apache läuft unter User und Group nobody. In den VirtualHost-Einträgen werden User und Group der "Kunden" zugewiesen, sowie open_basedir und upload_tmp_dir für PHP gesetzt:
DocumentRoot /home/userXX/html
User userXX
Group users
ScriptAlias /cgi-bin/ /home/userXX/html/cgi-bin/
php_admin_value open_basedir /home/userXX
php_admin_value upload_tmp_dir /home/userXX/phptmp
Folgende Probleme sind bei dieser Konstellation aufgetaucht:
1.) Bisher hatte ich so verstanden, daß PHP im safe_mode die UID des Ausführenden und des Besitzers einer Datei prüft, und nur bei Übereinstimmung das Ausführen zulässt.
Wenn ich aber im Homeverzeichnis eines Users eine root gehörende php-Datei mit Rechten -rw-r--r-- liegen habe, führt mod_php diese aus, obwohl sie nicht dem User des Verzeichnisses gehört. Erst wenn ich die Rechte für "Andere" entferne, kann PHP diese als 'nobody' nicht mehr ausführen.
Vermutlich unterlag ich also einem Irrtum. PHP überprüft nicht nur den Nutzer, sondern richtet sich auch, bzw. vor allem nach den Nutzerrechten.
Ist dieses Verhalten so wie beschrieben korrekt und habe ich einfach nur nicht richtig in der Doku gelesen, oder kann ich mod_php "zwingen" nur dem User gehörende Skripte auszuführen?
2.) Da PHP ja zusammen mit dem Apachen als 'nobody' arbeitet, schreibt PHP auch Dateien als 'nobody' auf die Platte. Dies ergibt seltsamerweise ein Problem, wenn das PHP-Skript eines Users versucht in ein so generiertes Verzeichnisse (drwxr-xr-x) zu schreiben. Dies funktioniert dann nämlich nicht und wird mit:
[Thu Jun 27 18:14:43 2002] [error] PHP Warning: SAFE MODE Restriction in effect. The script whose uid is 639 is not allowed to access newdir owned by uid 65534 in /home/userXX/html/test/php/makefile.php on line 1
abgebrochen.
Wenn das Verzeichnis dem richtigen User gehört (per Hand korrigiert) bekomme ich immerhin folgende Fehlermeldung:
[Thu Jun 27 18:19:12 2002] [error] PHP Warning: mkdir() failed (Permission denied) in /home/ws4/html/test/php/makefile.php on line 1
Erst wenn für "Others" auch Schreibrechte existieren (drwxr-xrwx), kann in dieses Verzeichnis geschrieben werden.
Es scheint so, als wenn PHP einmal nicht schreibt weil das schreibende Skript einem anderen User gehört, als das Verzeichnis (unterhalb des gleichen open_basedir) und das andere mal, weil PHP als 'nobody' keine Schreibrechte für das Verzeichnis besitzt.
Gibt es für diese Problematik eine Lösung auf Ebene der Konfiguration von PHP und/oder Apache, oder muss etwas an den Dateirechten verändert werden, so daß PHP in die selbst erzeugten Verzeichnisse wieder schreiben kann?
Ich hoffe, nicht bis zur nächsten Version von Apache/PHP warten zu müssen, sondern die Dokumentation schlecht gelesen zu haben. ;))
Gruß Alex
--
http://www.google.de/search?hl=de&safe=off&q=Rechtschreibung+Standart
DocumentRoot /home/userXX/html
User userXX
Group users
ScriptAlias /cgi-bin/ /home/userXX/html/cgi-bin/
php_admin_value open_basedir /home/userXX
php_admin_value upload_tmp_dir /home/userXX/phptmp
Folgende Probleme sind bei dieser Konstellation aufgetaucht:
1.) Bisher hatte ich so verstanden, daß PHP im safe_mode die UID des Ausführenden und des Besitzers einer Datei prüft, und nur bei Übereinstimmung das Ausführen zulässt.
Nein.
"When safe_mode is on, PHP checks to see if the owner of the current script matches the owner of the file to be operated on by a file function."
PHP prüft lediglich, ob eine zu bearbeitende Datei dem Benutzer gehört, dem auch das Skript gehört, welches diese Datei bearbeiten will. Mit dem Benutzer, unter dem Apache läuft, hat das nichts zu tun.
Daß diese Prüfung ein fürchterliches Hindernis sein kann, hast Du gerade erlebt. Insbesondere, wenn PHP auf Dateien zugreifen soll, die es selbst geschrieben hat, gibt es sinnloserweise Ärger, weil die Dateien vom Apache-Benutzer erzeugt wurden, nicht vom Skripteigentümer.
Es gibt anscheinend eine Möglichkeit, diese Prüfungen irgendwie nur auf Gruppenbasis durchzuführen oder ähnliches. Schau dazu bitte mal in Deine php.ini, in der eh miesen Seite zur PHP-Konfiguration ist diese Einstellung nicht beschrieben.
Andere Möglichkeit wäre, PHP über CGI laufen zu lassen. Dann können alle PHP-Skripte unter dem Benutzer laufen, dem die Skripte gehören und dementsprechend werden Dateisystem-Zugriffsrechte auch sinnvoll beachtet.
Diese Lösung hat dann aber wieder andere Nachteile.
Gruß,
soenk.e
Hallo
DocumentRoot /home/userXX/html
User userXX
Group users
ScriptAlias /cgi-bin/ /home/userXX/html/cgi-bin/
php_admin_value open_basedir /home/userXX
php_admin_value upload_tmp_dir /home/userXX/phptmp
[...]
PHP prüft lediglich, ob eine zu bearbeitende Datei dem Benutzer gehört, dem auch das Skript gehört, welches diese Datei bearbeiten will. Mit dem Benutzer, unter dem Apache läuft, hat das nichts zu tun.
Daß diese Prüfung ein fürchterliches Hindernis sein kann, hast Du gerade erlebt. Insbesondere, wenn PHP auf Dateien zugreifen soll, die es selbst geschrieben hat, gibt es sinnloserweise Ärger, weil die Dateien vom Apache-Benutzer erzeugt wurden, nicht vom Skripteigentümer.
Irgendwie finde ich das von den Entwicklern nicht weit sehr gedacht (ich will natürlich niemandem zu nahe treten :). Wieso kann PHP im safe_mode eine Datei nicht lesen, die durch ein PHP-Skript des Nutzers erstellt wurde? (wieso das so ist ist klar, aber nicht warum das so implementiert wurde :))
Es gibt anscheinend eine Möglichkeit, diese Prüfungen irgendwie nur auf Gruppenbasis durchzuführen oder ähnliches. Schau dazu bitte mal in Deine php.ini, in der eh miesen Seite zur PHP-Konfiguration ist diese Einstellung nicht beschrieben.
Dann müsste ich aber den Apachen der Gruppe der User zuordnen (users), oder alle Userverzeichnisse auf 'nobody' "umchownen". Irgendwelche Probleme mit umask höre ick aber jetzt schon "trapsen". Neu erzeugte Verzeichnisse sind im Momement ja auch für die Gruppe nicht beschreibbar (was imho auch sinnvoll ist und so bleiben sollte).
Ich habe safe_mode wieder abgeschaltet, und vertraue im Moment nur auf open_basedir. Das scheint auch zu genügen, zumindest um das Einlesen "fremder" Dateien zu unterbinden. Was allerdings bei system() usw. passieren kann, bzw. welchen Einfluss open_basedir darauf nimmt, habe ich nocht nicht herausbekommen.
Allerdings kann zwar jetzt PHP die selbst erzeugten Dateien und Verzeichnisse lesen - ein User kann diese aber sicherlich nicht per FTP oder über ein CGI-Skript löschen. :(
Andere Möglichkeit wäre, PHP über CGI laufen zu lassen. Dann können alle PHP-Skripte unter dem Benutzer laufen, dem die Skripte gehören und dementsprechend werden Dateisystem-Zugriffsrechte auch sinnvoll beachtet.
Diese Lösung hat dann aber wieder andere Nachteile.
Darauf wollte ich eigentlich gerne verzichten, zumal CONFIXX afaik mod_php benötigt :) Kann man Module und Interpreter parallel bzw. <VirtualHost>-abhängig unter einem Apachen laufen lassen?
Gruß Alex
--
http://www.google.de/search?hl=de&safe=off&q=Rechtschreibung+Standart
PHP prüft lediglich, ob eine zu bearbeitende Datei dem Benutzer gehört, dem auch das Skript gehört, welches diese Datei bearbeiten will. Mit dem Benutzer, unter dem Apache läuft, hat das nichts zu tun.
Irgendwie finde ich das von den Entwicklern nicht weit sehr gedacht (ich will natürlich niemandem zu nahe treten :).
Das haben sie ja auch in der Einleitung zu Safe Mode geschrieben: Der Ort, an dem diese Zugriffsprüfung eingebaut wurde (also im PHP-Interpreter), ist eigentlich falsch, aber auf Webserver- oder Betriebssystemebene sieht's halt bei der Modullösung noch düsterer aus.
Wieso kann PHP im safe_mode eine Datei nicht lesen, die durch ein PHP-Skript des Nutzers erstellt wurde? (wieso das so ist ist klar, aber nicht warum das so implementiert wurde :))
Dazu muß das Skript die neue Datei, die ja in jedem Fall anfangs dem Apache-User gehört, an den Skripteigentümer verschenken. Ich bin nicht der Unix-Meister, aber zumindest auf Shell-Ebene ist so eine Verschenkungsaktion nur für einen möglich: root.
Wenn Du von einem normalen User-Account versuchst, ein chown durchzuführen, kriegst Du ein "operation not permitted" zurück.
Wenn Du aber den Apache nur wegen der PHP-Zugriffsrechte unter root laufen lässt, kommst Du vom Regen in die Traufe, weil damit andere, noch schlimmere Sicherheitslöcher geöffnet werden könnten.
Ich hoffe mal, diese Darstellung ist so richtig.
Ich habe safe_mode wieder abgeschaltet, und vertraue im Moment nur auf open_basedir. Das scheint auch zu genügen, zumindest um das Einlesen "fremder" Dateien zu unterbinden. Was allerdings bei system() usw. passieren kann, bzw. welchen Einfluss open_basedir darauf nimmt, habe ich nocht nicht herausbekommen.
open_basedir kann auf jeden Fall nicht verhindern, daß ein per system() aufgerufenes Programm beliebige Dateien öffnet - allerdings steht da ja dann wieder das Betriebssystem davor.
Allerdings kann zwar jetzt PHP die selbst erzeugten Dateien und Verzeichnisse lesen - ein User kann diese aber sicherlich nicht per FTP oder über ein CGI-Skript löschen. :(
Wenn das Verzeichnis vom User erstellt wurde, hat er sicher dort auch standardmäßig Schreibrechte und kann somit alle Dateien in "seinem" Verzeichnis löschen - egal wem sie gehören. Zumindest funktioniert's hier :)
Andere Möglichkeit wäre, PHP über CGI laufen zu lassen. Dann können alle PHP-Skripte unter dem Benutzer laufen, dem die Skripte gehören und dementsprechend werden Dateisystem-Zugriffsrechte auch sinnvoll beachtet.
Diese Lösung hat dann aber wieder andere Nachteile.
Darauf wollte ich eigentlich gerne verzichten, zumal CONFIXX afaik mod_php benötigt :) Kann man Module und Interpreter parallel bzw. <VirtualHost>-abhängig unter einem Apachen laufen lassen?
Da AddType auch in VirtualHost-Abschnitten einsetzbar ist, könnte das durchaus möglich sein. Ob das nun sinnvoll ist.. Ich hätte leichte Bauchschmerzen, wenn für jeden Zugriff der PHP-Interpreter neu geladen und gestartet wird - aber mein erster Rechner lief auch mit 8 MHz, hatte 512 KByte Speicher und weitere 512k kosteten über 500 Mark, sowas prägt Sparsamkeit :)
Gruß,
soenk.e