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

Dieser Inhalt ist unter einer Creative-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 ist schon 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.



© 2016. Hetzner Online GmbH. Alle Rechte vorbehalten.