Apache2 mit PHP FastCGI

Aus Gentoo Linux Wiki

Wechseln zu: Navigation, Suche
Dieser Artikel ist Teil der HOWTO Sammlung.
Installationsmethoden LiveCDs Kernel & Hardware Laptops & Notebooks Portage System Netzwerke & Services X Software Anderes alphabetischer HOWTO Index


Inhaltsverzeichnis

[Bearbeiten] Vorbereitung

Zuerst müssen wir mal Root sein, damit wir auch installieren und konfigurieren können.

[Bearbeiten] Use-Flags

PHP muss mit dem USE-Flags cgi gebaut werden, zusätzlich sollte man noch discard-path und force-cgi-redirect übersetzt werden; beides sind lokale USE-Flags und Sicherheitsfeatures. Welche weiteren Module man in PHP benötigt, sollte jeder selbst herausfinden und entscheiden. Das MySQL Flag ist wohl häufig benötigt.

Datei: /etc/portage/package.use
dev-lang/php -apache2 cgi cli discard-path force-cgi-redirect


Das USE-Flag apache2 wird für PHP an sich nicht benötigt, da wir PHP ja als CGI betreiben wollen. Für mod_fastcgi (und z.B. subversion, wenn man das installieren will) benötigt man es aber. Global bleibt es also aktiviert, für PHP jedoch deaktiviert.

Datei: /etc/make.conf
USE="apache2 ... fastcgi ... mysql ... php ... unicode ..."


[Bearbeiten] Installation

Nachdem jetzt die richtigen USE-Flags gesetzt sind, können wir das ganze installieren.

Code: Installation von Apache, PHP und mod_fastcgi
# emerge -va apache php mod_fastcgi


Das war dann eigentlich auch schon alles. PHP ist ein recht großes Paket, und je nachdem welche Funktionen man noch aktiviert hat, kann das Kompilieren schon mal ein Weilchen dauern.

[Bearbeiten] Konfiguration

Am Ende dieses Abschnitts möchten wir einen Webserver haben, der PHP per FastCGI aufruft und bei Bedarf pro VHost eigene PHP-Konfigurationen nutzen kann.

[Bearbeiten] Verzeichnisstruktur

Webpräsenzen legt Gentoo standardmäßig unterhalb /var/www ab. Das DocumentRoot jedes VHost liegt dann unter /var/www/VHOST/htdocs. Will man webapp-config nutzen (z.B. für phpmyadmin, gallery, wordpress o.ä.), sollte man sich daran auch halten.

Wir benötigen in jedem Vhost ein Verzeichnis für die Konfiguration, z.B. conf. Dort kann dann für jeden Vhost eine php.ini abgelegt werden. Falls die dort nicht zu finden ist, wird automatisch die php.ini im Verzeichnis /etc/php/cgi-php5/ verwendet.

Zusätzlich wird noch für jeden VHost eine Start-Datei benötigt. Dazu erzeugen wir ein Unterverzeichnis.

Code: Verzeichnis-Struktur
cd /var/www
mkdir -p php-fcgi-scripts/localhost
mkdir localhost/conf


[Bearbeiten] PHP-Start-Skript

In dem eben angelegten Verzeichnis für Skripte müssen wir für jeden VHost ein Start-Skript erstellen, welches PHP-CGI-Instanzen startet.

Datei: /var/www/php-fcgi-scripts/localhost/php-fcgi-starter
 #!/bin/sh
 PHPRC="/var/www/localhost/conf"
 export PHPRC
 PHP_FCGI_CHILDREN=4
 export PHP_FCGI_CHILDREN
 exec /usr/bin/php-cgi


Wir geben mit der Variable PHPRC den Pfad zur Konfigurationsdatei an. Wichtig dabei ist, dass nur der Pfad angeben wird, der Dateiname am Ende wird nicht mit angegeben. PHP_FCGI_CHILDREN gibt an, wieviele Kinder gestartet werden sollen. So viele PHP-Prozesse wird man nach dem Start des Apachen im System sehen können. Schlussendlich wird noch das PHP-Binary aufgerufen. Bei Bedarf werden von FastCGI neue Prozesse gestartet. Man kann die Angabe der Kindprozesse auch weglassen, dann werden alle benötigten Kinder bei Bedarf gestartet, was eine erhöhte Last (und Verzögerung) beim ersten Aufruf zur Folge haben kann.

Nun müssen wir uns eine Sache überlegen: Wie benötigen einen normalen User, dem die Daten im Default Vhost (localhost) gehören sollen. Diesen Nutzer müssen wir gleich angeben.

[Bearbeiten] Globale Konfiguration

Bei der Installation legt mod_fastcgi eine Datei in /etc/apache2/modules.d ab. Diese Datei müssen wir nun editieren.

Datei: /etc/apache2/modules.d/20_mod_fastcgi.conf
<IfDefine FASTCGI>
  <IfModule !mod_fastcgi.c>
   LoadModule fastcgi_module    modules/mod_fastcgi.so
  </IfModule>

  <IfModule mod_fastcgi.c>
    AddHandler fastcgi-script .fcg .fcgi

    FastCgiWrapper /usr/sbin/suexec2
    FastCgiServer /var/www/php-fcgi-scripts/localhost/php-fcgi-starter -user DEFAULT_VHOST_USER -group DEFAULT_VHOST_GROUP

    AddHandler php-fastcgi .php
    Action php-fastcgi /cgi-bin/php-fcgi-starter
    AddType application/x-httpd-php .php

    <Location /cgi-bin/php-fcgi-starter>
      SetHandler fastcgi-script
      Options +ExecCGI
    </Location>

    AddDirectoryIndex index.php

  </IfModule>
</IfDefine>


Was haben wir hier definiert? Wir haben den Wrapper definiert, damit PHP dann als User läuft. Das übernimmt suexec2. Hier gab es auf meinem System noch ein Problem: Der Webserver durfte suexec2 nicht aufrufen. Der Aufruf schien nicht als Root aber auch nicht mit der Gruppe apache zu erfolgen. Genauer konnte ich das nicht eingrenzen, jedoch scheint auf einem Debian-System suexec2 generell mit den Rechten 4755 installiert zu werden.

Code: Anpassen der Rechte für /usr/sbin/suexec2
ls -l /usr/sbin/suexec2
-rws--x--- 1 root apache 13248 Nov 24 00:04 /usr/sbin/suexec2
chmod o+x /usr/sbin/suexec2
ls -l /usr/sbin/suexec2
-rws--x--x 1 root apache 13248 Nov 24 00:04 /usr/sbin/suexec2


Nun kann suexec2 auch gestartet werden.

Des Weiteren haben wir ein Start-Skript definiert. Zu den Berechtigungen komme ich später noch. Wir haben außerdem noch festgelegt, wie .php Dateien behandelt werden sollen, dass in dem cgi-bin Verzeichnis CGIs ausgeführt werden dürfen und dass index.php auch als Index-Datei zählt.

Jetzt müssen wir noch fastcgi aktivieren. Dies geschieht so:

Datei: /etc/conf.d/apache2
 ...
 APACHE2_OPTS="-D DEFAULT_VHOST -D FASTCGI -D SUEXEC"
 ...


[Bearbeiten] VHost-spezifische Konfiguration

Pro Vhost wird eine Konfigurationsdatei benötigt. Wir bearbeiten zuerst die Datei für den Default VHost.

Datei: /etc/apache2/vhosts.d/00_default_vhost.conf
 NameVirtualHost *:80
 <IfDefine DEFAULT_VHOST>
   <VirtualHost *:80>
     DocumentRoot "/var/www/localhost/htdocs"
     <Directory "/var/www/localhost/htdocs">
       Options Indexes FollowSymLinks +ExecCGI
       AllowOverride None
       Order allow,deny
       Allow from all
     </Directory>
     ScriptAlias /cgi-bin/ /var/www/php-fcgi-scripts/localhost/
     SuexecUserGroup "DEFAULT_VHOST_USER" "DEFAULT_VHOST_GROUP"
   </VirtualHost>
 </IfDefine>


Wir haben hier also den Pfad zu unserem Startskript angegeben und User/Gruppe, unter dem die Skripte ausgeführt werden sollen, angegeben.

[Bearbeiten] korrekte Rechte

Korrekte Rechte der Dateien sind extrem wichtig. Wenn die Dateien falsche Rechte haben, verweigert suexec2 seinen Dienst.

Code: Rechteanpassung
# cd /var/www/php-fcgi-scripts
# chown -R DEFAULT_VHOST_USER:DEFAULT_VHOST_GROUP localhost
# chmod 755 localhost/php-fcgi-starter
# chattr -V +i localhost/php-fcgi-starter
# lsattr localhost/php-fcgi-starter
# ----i-------- localhost/php-fcgi-starter


Durch chattr +i erreicht man, dass das Start-Skript nicht geändert werden kann. Nicht einmal von root, dafür muss das immutable Bit erst wieder entfernt werden. Wenn man das nicht macht, könnten Benutzer die Dateien überschreiben und somit durch "böse" Skripte ersetzen und somit die Systemstabilität gefährden.

Wichtig ist auch, dass auch das Verzeichnis des Startskripts dem User gehören muss, sonst gibt es Fehlermeldungen im suexec_log.

Je nach Anwendungsfall kann es gewünscht sein, dass ein Nutzer seine php.ini Datei selbst bearbeiten kann. Dann sollte die globale php.ini ins oben erstellte conf-Verzeichnis des VHosts kopiert werden und die Besitzrechte an den User angepasst werden.

Das htdocs-Verzeichnis des VHost sollte natürlich nun auch dem Nutzer gehören, damit uns das Ganze überhaupt etwas bringt - nämlich Schreibrechte von PHP im DocumentRoot ohne globale Schreibrechte.

[Bearbeiten] Fertigstellen/Fazit

Nun können wir unser Glück versuchen und den Apachen starten. Wenn alles erfolgreich war, sollte das dann so aussehen:

Code: Apache Start
 # /etc/init.d/apache2 start
 * Starting apache2 ...                     [ ok ]


Mögliche Fehlermeldungen und die mögliche Bedeutung habe sind unten aufgeführt.

Was haben wir also erhalten? Einen Apache Webserver mit FastCGI und PHP. Dies gibt uns die Möglichkeit, PHP als User laufen zu lassen. Die Vorteile:

  • Schreibrechte auf die Webpräsenz ohne globale Schreibrechte
  • angepasste php.ini Dateien
  • Möglichkeit des Einsatzes verschiedener PHP-Versionen pro VHost bzw. sogar innerhalb eines VHosts

[Bearbeiten] Credits, Kommentare, etc ...

[Bearbeiten] Credits

Das HowTo lehnt sich an vor allem an http://www.debianhowto.de/doku.php/de:howtos:sarge:apache2_php-fcgi an. Ich danke den Autoren für dieses Howto.

[Bearbeiten] Fehlermeldungen

Hier sollen einige Fehlermeldungen aufgelistet werden und der mögliche Grund dafür.

Datei: STDERR
 FastCgiWrapper: "/usr/sbin/suexec2" execute access for server (uid 4294967295, gid 4294967295) 
                 failed: execute not allowed
  • Grund: Keine Rechte für "other" auf /usr/sbin/suexec2. Die Angaben von uid und gid sind extrem daneben, daran kann man nicht sehen, als welcher Nutzer versucht wird, die Datei aufzurufen.
  • Lösung: chmod o+x /usr/sbin/suexec2
Datei: /var/log/apache2/error_log
 [Sun Nov 26 17:26:03 2006] [warn] FastCGI: server "/var/www/php-fcgi-scripts/localhost/php-fcgi-starter"
                                   (uid 1000, gid 1000) started (pid 24432)
 [Sun Nov 26 17:26:03 2006] [warn] FastCGI: server "/var/www/php-fcgi-scripts/localhost/php-fcgi-starter" 
                                   (pid 24432) terminated by calling exit with status '120' 
Datei: /var/log/apache2/suexec_log
 [2006-11-26 17:26:18]: target uid/gid (1000/1000) mismatch with directory (1000/1000) or program (81/1000)
  • Grund: Die PHP-Start-Datei oder das Verzeichnis gehört nicht dem User, der in der FastCGI- oder VHost-Konfiguration angegeben wurde.
  • Lösung: chown -R DEFAULT_VHOST_USER:DEFAULT_VHOST_GROUP /var/www/php-fcgi-scripts/localhost
Datei: /var/log/apache2/error_log
 [Sat Nov 25 17:23:35 2006] [warn] FastCGI: server "/var/www/php-fcgi-scripts/localhostphp-fcgi-starter"
                                  (pid 8135) terminated by calling exit with status '108'  
Datei: /var/log/apache2/suexec_log
 [2006-11-25 17:23:40]: uid: (user/user) gid: (apache/apache) cmd: php
 [2006-11-25 17:23:40]: cannot run as forbidden gid (81/php)
 [2006-11-25 17:27:09]: uid: (apache/apache) gid: (apache/apache) cmd: php
 [2006-11-25 17:27:09]: cannot run as forbidden uid (81/php)
  • Grund: Es wurde ein FastCGI-User mit UID und GID <1000 angegeben. Dies ist nicht erlaubt.
  • Lösung: User und Gruppe mit UID/GID >=1000 angeben. Ändern des Besitzers des Skripts nicht vergessen.
Datei: /var/log/apache2/error_log
 [Sun Nov 26 16:05:02 2006] [error] FastCGI: access for server (uid 4294967295, gid 4294967295) failed: 
                                    read not allowed
 [Sun Nov 26 16:05:02 2006] [error] FastCGI: can't create dynamic directory "/var/run/fastcgi/dynamic": 
                                    access for server (uid 4294967295, gid 4294967295) failed: 
                                    read not allowed
  • Grund: Scheinbar kann kein Socket in dem angegebenen Verzeichnis beim Starten erzeugt werden.
  • Lösung: Keine. Ein chmod 777 für das Verzeichnis lässt zwar die Fehlermeldung verschwinden, jedoch wird kein Socket dort abgelegt. Muss man wahrscheinlich ignorieren. Interessanterweise können später beim Aufruf einer Seite und dem damit verbundenen Erzeugen eines FastCGI-Prozesses Sockets in dem bemängelten Verzeichnis angelegt werden. Das scheint also ein Bug während des Startvorgangs zu sein - wohl der gleiche, der auch den Zugriff auf suexec verhindert. Kurzzeitig muss da wohl was unter einem völlig anderem User laufen.

[Bearbeiten] Kommentare

'Persönliche Werkzeuge