Hetzner - DokuWiki
Apache PHP5 fcgi und SuExec
Inhaltsverzeichnis |
Apache2 mit PHP5 als suExec/ Fcgid Variante
Über
Changes
- 06.04.2010 Korrekturen im Bereich php.ini, Die Berechtigung war falsch, der User konnte seine php.ini ändern
- 10.02.2010 Korrekturen im Bereich php.ini, damit die genutzt werden kann
- 07.02.2010 " bei EOF entfernt, damit Leute die Ihre Domains mit Skripten erzeugen nicht in Probleme laufen. Tempdir im fcgistarter exportiert.
- 10.08.2009 Apache-Pakete korrigiert, Portangabe in vHosts ergänzt
- 16.02.2009 suexec muß aktiviert sein, Rechtschreibfehler
- 12.11.2008 chmod für php-fcgi-starter ergänzt
- 01.10.2008 Rechte für php-fcgi-starter ergänzt, Hinweise zu Webanwendungen
- 25.07.2008 Lücken gefüllt, Fehler ausgebessert - sollte vollständig sein
- 24.07.2008 erste Version - wird noch gefüllt
Author: Jan Scholten
devnull [at] rootsvr [dot] de
Copyright und Lizenz
http://creativecommons.org/images/public/somerights20.gif Dieser Inhalt ist unter einer Cretive-Commons Lizenz lizensiert.
Feedback
Feedback zu diesem Dokument ist natürlich willkommen, einfach eine Mail an den Autor schicken.
Einleitung / Abstrakt
Fast jeder Serverbetreiber wird (zumindest wenn er Kunden hat) einen Webserver Server nutzen wollen oder müssen.
Bei der einfachste Variante mit mod-php läuft der PHP Interpreter mit den gleichen Rechten wie der Webspace. Ist praktisch, er kann alles lesen und schreiben, man braucht nichts (?) einzustellen.
Nachteil ist: er kann wirklich alles lesen und schreiben. Z.B. die Verzeichnisse eines anderen Kunden. Wer mag testet mit webadmin ob man aus seinem Verzeichnis rauskommt.
Dann gibt es mod-suphp, das startet für jede PHP Seite einen extra Interpreter mit entsprechenden Userrechten.
Das ists chon besser! Aber leider sehr sehr langsam, da wirklich für jeden Seitenaufruf einmal PHP geladen wird und der Interpreter danach beendet wird
Eine (in meinen Augen) bessere Lösung ist es php als fastcgi zu starten. dabei wird PHP pro User einmal gestartet und dann aber weiterverwendet. Das ermöglicht es pro User eigene php.inis aber auch eigene php Versionen (PHP4 anyone?) zu verwenden und ist deutlich schneller - nur der erste Aufruf dauert ein wenig länger.
In meinen Augen die beste Lösung auch wenn man bei wirklich großen Kundenzahlen eher auf suphp gehen sollte. da für jeden User(account) ein php vorgehalten wird, kann das auf die Dauer einigen RAM nutzen.
Ich benutze diese Konfiguration in einer suExec + fcgid, das heißt jede Domain läuft unter einem User.
Dies harmoniert schön mit den individuellen FTP Usern in meinem PureFTPd HowTo
Für Diskussionen/Korrekturen bitte Forenthread benutzen benutzen
Hinweise
Vorneweg einige Einschränkungen:
Dies stellt kein Copy und Paste Howto da. Es können einzelne Teilschritte vergessen worden sein, auch Rechtschreibfehler sind vorgekommen. Wer keine Ahnung hat wird sich möglicherweise ein kaputtes System schaffen - testen (VMWare) und debug-fähig sollte man sein.
Will man diese Konfiguration nutzen erhält man ein System, welches deutlich sicherer ist als eine Standard mod_php installation.
Nachteile gibt es auch:
- Es ist langsamer als mod_php (nach dem ersten Starten des Prozesses aber nicht übermäßig)
- Man kann keine Webanwendungen als Debianpakete installieren. Genauer: man kann keine Debianpakete installieren ohne nachher seine Konfiguration (vhost/php.ini) entsprechend anzupacken.
Die Debian pakete setzen Apache als www-data vorraus, suexec und open_base_dir spielen da nicht ohne weiteren mit. Am stresfreiesten installiert man phpmyadmin und Co indem man sie selber heruntergeläd und installiert. Um Updates muß man sich dann aber selber kümmern.
- Der Speicherbedarf kann bei vielen Usern sehr groß werden. Wer plant 1000 unterschiedliche Domains und damit 1000 User und PHP Instanzen auf seiner Kiste zu haben sollte sich ggf andere Möglichkeiten suchen.
Installation
Wir installieren apache2, php5 als cgi/fcgi und mod-fcgid (das ganze sollte mit mod-fastcgi ähnlich funktionieren), damit suexec klappt, brauchen wir auch das (alternativ: apache2-suexec-custom)
aptitude install libapache2-mod-fcgid php5-cgi apache2 apache2-mpm-worker apache2-suexec
Nicht wundern die php Variante ist trotz des Namens auch fcgi tauglich.
Danach das fcgid Modul aktivieren. Auch suexec muß gestartet werden.
a2enmod fcgid a2enmod suexec
User Anlegen
Jetzt brauchen wir pro Webaccount einen user, unter dessen Rechte dann PHP läuft.
adduser example
Damit Apache später auch die dem usergehörenden html seiten lesen kann muß er den entsprechenden Gruppe angehören:
adduser www-data example
Verzeichnisse erzeugen
Bei der Verzeichnisstruktur sind die Rechte sehr wichtig, für suexec muß bei der Debian Variante alles unterhalb von /var/www liegen und die User IDs größer als 1000 sein.
Ich schlage folgende Struktur vor, damit alle wichtigen Daten zusammen liegen:
/var/www/example.com/conf/ # hier liegt die php.ini für diese Domain /var/www/example.com/docs/ # hier das normale Webroot /var/www/example.com/logs/ # Logfiles /var/www/example.com/tmp/ # Session Daten/ temporäre Daten /var/www/example.com/php-fcgi/ # das Startscript für fcgid
(in meinem Fall habe ich sowohl bei User als auch den Verzeichnissen unterhalb von /var/www einen Domänennamen bzw. etwas ähnliches .. das erleichtert die Zuordnung.
Also anlegen und die (richtigen) Rechte setzen:
mkdir -p /var/www/example.com/conf mkdir /var/www/example.com/docs mkdir /var/www/example.com/logs mkdir /var/www/example.com/tmp mkdir /var/www/example.com/php-fcgi chown root:example /var/www/example.com chmod 750 /var/www/example.com chown example:example /var/www/example.com/* chmod 750 /var/www/example.com/* chmod 550 /var/www/example.com/conf
php.ini anpassen
Wir kopieren die php.ini aus /etc/php5/cgi/ in unser Verzeichnis:
cp /etc/php5/cgi/php.ini /var/www/example.com/conf/
Wir passen php an unsere Bedürfnisse an und sorgen für ein bischen Sicherheit:
open_basedir = /var/www/example.com/docs/:/var/www/example.com/tmp/ upload_tmp_dir = /var/www/example.com/tmp session.save_path = /var/www/example.com/tmp
Die wichtigste Einstellung ist das openbasedir, welches den php Prozess in die beiden relevanten Verzeichniss einsperrt. die anderen beiden sorgen dafür das diese Instanz ihre Sessiondaten, uploads etc. im eigenen tmp Verzeichnis anlegt.
Für weitere Vorschläge bin ich offen (DocRoot? Mehr Speicher?)
Damit die php.ini verwendet wird muß man die Rechte anpassen
chown example:example php.ini chmod 440 php.ini
Bedenken sollte man das module die man installiert automatisch in jedem vhost aktiv sind (mysql, pdo, xcache etc.) da Debian standardmäßig /etc/php5/cgi/conf.d liest. Dies kann man unterbinden indem man den symlink auf conf.d löscht. Danach muß man eventuell benötigte Module aber pro vhost seperat installieren, was zumindest bei oft benötigten Modulen/extensions (gd oder mysql) nervig ist. Alternativ kann man einzelne extensions aus dem conf.d entfernen und nur bestimmten vHost über ihre php.ini zugänglich machen (Xcache o.ä.)
fcgi Starter anlegen
In /var/www/example.com/php-fcgi legen wir eine Datei Namens php-fcgi-starter an:
cat > /var/www/example.com/php-fcgi/php-fcgi-starter << EOF #!/bin/sh PHPRC="/var/www/example.com/conf/" export PHPRC export TMPDIR=/var/www/example.com/tmp exec /usr/bin/php5-cgi EOF
Schenken das ganze dem User, ansonsten meckert suexec und es geht nicht:
chown example:example /var/www/example.com/php-fcgi/php-fcgi-starter
Setzen auch noch die richtigen Rechte, auch sonst makelt suexec - 750 kommt uns grade recht:
chmod 750 /var/www/example.com/php-fcgi/php-fcgi-starter
Damit der User daran aber nichts ändern kann setzen wir das immutable bit:
chattr +i -V /var/www/example.com/php-fcgi/php-fcgi-starter
Apache Vhost anlegen
Apache muß gesagt werden das für ein bestimmtes Verzeichnis (unsere Domains) ein bestimmtes Startscript für fcgi zuständig ist.
Ich habe mit der folgenden Version gute Erfahrungen gemacht,
cat > /etc/apache2/sites-available/example.com << EOF
<VirtualHost *:80>
ServerAdmin me@example.com
ServerName example.com
ServerAlias www.example.com
SuexecUserGroup example example
AddHandler fcgid-script .php
DocumentRoot "/var/www/example.com/docs"
DirectoryIndex index.htm index.html index.php
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory "/var/www/example.com/docs">
Options Indexes MultiViews FollowSymLinks +ExecCGI
FCGIWrapper /var/www/example.com/php-fcgi/php-fcgi-starter .php
Order allow,deny
allow from all
</Directory>
ErrorLog /var/www/example.com/logs/error.log
LogLevel warn
CustomLog /var/www/example.com/logs/access.log combined
ServerSignature On
</VirtualHost>
EOF
Dann die Site aktivieren:
a2ensite example.com
Die SuexecUserGroup spezifiziert den User unter dem das ganze abläuft und muß natürlich mit den Owner des jeweiligen Verzeichnisse übereinstimmen.
Fehlersuche
- Stimmen die Berechtigungen?
- Was sagen die Logfiles /var/www/example.com/logs/error.log oder /var/log/apache2/suexec.log
- Apache kannphp haber keine html Dateien -> ist www-data der Gruppe zugehörig?
Weitere Aussichten
Andere Sprachen mit fastcgi Schnittstelle sollten sich ebenso einsetzen lassen.


