Lokaler Apache/PHP-Testserver

Ich entwickle oft "PHP 5"-Programme - auch unterwegs. Auf einem Laptop musste ich vor kurzem einen lokalen Apache-Server einrichten, um auch ohne Netzwerkanbindung Programme testen zu können. Der Server sollte natürlich PHP5 unterstützen und für eine bestimmte Testdomaine - "devdomain" - SSL-fähig sein. Hierzu muss man auf die Schnelle virtuelle Domainen einrichten. Das Ganze unter Opensuse 11.3.

Vielleicht ist die nachfolgende Vorgehensweise zur Lösung dieser Aufgabenstellung auch für andere interessant.

/etc/host-Einträge

Der Rechner soll später autonom - d.h. ohne Netzverbindung funktionieren. Ein DNS-Dienst ist für ein rein lokales System überflüssig. Für einen lokalen, autonomen Testserver kann für die notwendigen Einträge in der Datei "/etc/hosts" das Loopback-Interface verwenden. Die Einträge können dann etwa so aussehen:

127.0.0.1         localhost.localdomain         localhost

127.0.0.2         mylap.myprivatedomain.de         mylap

127.0.0.2         devdomain

Der erste Eintrag ist ein Standard Opensuse-Entrag, wie er bei einer automatischen Installation erzeugt wird. Den zweiten benötige ich für andere Programme. Interessant für unsere Problemstellung ist die dritte Zeile. Die dortige IP-Adresse ist u.a. wichtig für das spätere Aufsetzen der IP-basierten virtuellen Domaine "devdomain".

Es gibt im Internet immer wieder Diskussionen um die Verwendung der Loopback-Adresse - ich denke, die oft angeführten Gegen-Argumente kann man im Zusammenhang mit dem beschriebenen Szenario getrost ignorieren. Ein System mit aktiven Netzwerkschnittstellen benötigt natürlich noch mehr Einträge an passender Stelle in der "/etc/hosts" und ggf. eine Adress-Systematisierung über einen DNS-Server. Aber die Funktionalität eines autonomen Entwicklungs- und Test-Systems ist mit den Loopback-Adressen wirklich in hinreichender Weise gegeben.

Für die korrekte lokale Namensauflösung sollte "files" die Reihenfolge der Ressourcen im "hosts"-Eintrag der Datei "/etc/nsswitch.conf" anführen:

hosts:       files mdns4_minimal [NOTFOUND=return] dns

Grundinstallation Apache

Apache2 kann man unter Opensuse einfach über die Yast und die dortige Paketverwaltung installieren. Folgende Pakete aus dem Opensuse 11.3 Standard-Repository habe ich installiert:

  • apache2 (!)
  • apache2-devel (!)
  • apache2-doc
  • apache2-example-pages (!)
  • apache2-mod_dnssd
  • apache2-mod_perl
  • apache2-mod_php5 (!)
  • apache2-mod_python
  • apache2-prefork (!)
  • apache2-utils (!)
  • libapr-util1 (!)
  • libapr-util1-devel (!)
  • libapr1 (!)
  • libapr1-devel (!)

Nach der Installation und einem "rcapache2 start" sollte ein

http://localhost

im Browser bereits eine Seite mit dem schönen Text "It works!" anzeigen. Danach trägt man mit Yast den Apache2-Server in die Run-Level-Konfiguration ein, damit er automatisch z.B. in den Levels 3 und 5 gestartet wird.

Grundinstallation PHP5

Für eine relativ umfassende PHP5-Unterstützung sind für mich in der Regel folgende Pakete/Module von Bedeutung:

apache2-mod_php5, php-doc, php5, php5-bcmath, php5-bz2, php5-ctype, php5-devel, php5-dom, php5-gd, php5-hash, php5-iconv, php5-imagick, php5-json, php5-mbstring, php5-mcrypt, php5-mysql, php5-pdo, php5-pear, php5-phar, php5-sqlite, php5-tidy, php5-tokenizer, php5-xdebug, php5-xmlreader, php5-xmlwriter, php5-zip, php5-zlib

Die Zusammenstellung kann für umfangreiche Entwicklungsszenarien natürlich komplexer aussehen.

Hinweis zur Aktualisierung der PHP-Installation:
Um eine aktuelle PHP5-Installation unter Opensuse 11.2 zu erhalten (PHP 5.3.3) muss man ggf. die passenden Repositories unter

http://download.opensuse.org/repositories/server:/php/
http://download.opensuse.org/repositories/server:/php:/extensions/

in die Paketverwaltung einbinden. Über das zweite der genannten Repositories erhält man z.B. das Xdebug-RPM.

Modifikation an der php.ini

Auf einem Entwicklungssystem will man man Fehlermeldunge zu PHP5-Programmen sehen. Evtl. hat man auch Programme, die mit der Kurzform der Script-Tags "" statt lauffähig sein sollen. Um beim Einsatz der Funktion "date()" Warnungen zu vermeiden, stellt man auch die Standardzeitzone für das PHP-Modul ein. Für all das muss man entsprechende Modifikationen an der Datei

"/etc/php5/apache2/php.ini"

vornehmen. Entsprechende Einträge (plus ein paar mehr) :

  • short_open_tag = On
  • error_reporting = E_ALL & ~E_DEPRECATED
  • display_errors = On
  • log_errors = On
  • ignore_repeated_errors = Off
  • ignore_repeated_source = Off
  • register_globals = Off (immer gut)
  • include_path = ".:/usr/share/php5:/usr/share/php5/PEAR" (PEAR soll funktionieren)
  • date.timezone = Europe/Berlin

"Spiel-Zertifikat und SSL-Aktivierung unter Opensuse 11.3

Viele meiner PHP-Frameworks für Kunden erzwingen in der Regel einen HTTPS-Verbindung. Wenn ich das lokal testen will, komme ich um SSL also nicht herum. SSL geht nur über IP-basierte virtuelle Domainen. Für den Standardhost "localhost" ist dann zudem eine zweite separate virtuelle Domaine einzurichten.

SSL geht nicht ohne ein Minimal-Zertifikat. Für lokale Testzwecke reicht ein "Spiel-Zertifikat". (Im Browser fügt man dann bei Warnungen eine Ausnahmeregel für das Zertifikat ein.)

Unter Opensuse 11.3 erreicht man die notwendige Grundausstattung des Apache-Servers unter Benutzung von Apache-Tools durch folgende Kommandos:

  • a2enmod ssl
  • a2enflag SSL
  • /usr/bin/gensslcert (als root absetzen)
  • cp /etc/apache2/vhosts.d/vhost-ssl.template /etc/apache2/vhosts.d/vhost-ssl.conf
  • Anpassung der vhost-Dateien (s.u.)

Ein paralleler Blick in die "sysconfig"-Dateien des SUSE-Systems ist hier nicht verkehrt. Dafür kann man z.B. den sysconfig-Editor von Yast heranziehen. Im dortigen kategoriebaum bewegt man sich in den Zweig

"Netzwerke   >>>   WWW   >>>   Apache2".

Unter dem Eintrag "APACHE_MODULES" sollte man folgendes finden:

authz_host actions alias auth_basic authz_groupfile authn_file authz_user autoindex cgi dir include log_config mime negotiation setenvif status userdir asis imagemap ssl php5 authz_default

Unter dem Eintrag APACHE_SERVER_FLAGS sollte SSL auftauchen:

SSL

Hinweise:

  • Ein Extra-RPM für das SSL-Modul muss unter Opensuse 11.3 nicht installiert werden.
  • gensslcert erzeugt nur eine Spiel-Cert. Dabei werden folgende Dateien überschrieben:
  • /etc/apache2/ssl.crt/ca.crt
  • /etc/apache2/ssl.key/server.key
  • /etc/apache2/ssl.crt/server.crt
  • /etc/apache2/ssl.csr/server.csr
  • Der Virtual-Host für die SSL-Domaine muss IP-basiert (!) angelegt werden - also nicht namensbasiert. "*"-Angaben für die IP-Adressen werden mit Fehlermeldungen quittiert. In unserem Beispiel werden für das autonome Testsystem die Loopback-Adressen herangezogen.
  • Man darf nicht vergessen, dass man für einen Standardzugang "http://localhost" eine eigene virtuelle Domaine einrichten muss, da es bei virtuellen Domainen ohne Vorkehrungen keinen Standard-Host (Default-Web-Server) mehr gibt.

Konfigurationsdateien

Nachfolgend gebe ich (etwas verkürzt) an, welche Grundeinträge in zwei Konfigurationsdateien unter dem Verzeichnis

/etc/apache2/vhosts.d

notwendig sind, um das Ziel zu erreichen,

  • einen Standardhost ohne SSL-Verschlüsselung unter "http://localhost"
  • eine Testdomaine "devdomain" für Entwicklungszwecke über "https://devdomain"

ansprechen zu können:

Inhalt der Datei "ip-based_vhosts.conf" für den Standardserver

<VirtualHost *>

DocumentRoot /srv/www/htdocs

DirectoryIndex index.html index.html.var index.htm index.php index.php5

<Directory “/srv/www/htdocs”>

Options Indexes FollowSymLinks

AllowOverride None

Order allow,deny

Allow from all

</Directory>

</VirtualHost>

Hinweise:

  • Der Name der Datei kann beliebig gewählt werden !
  • Es wird hier kein "server-name angegeben" !!!! - Default-Server
  • Das Root-Verzeichnis für den Standardhost ist hier “/srv/www/htdocs”. Dort sind die Web-Dateien und PHP-Programme anzulegen.

Inhalt der Datei "vhost-ssl.conf" für den IP-basierten, SSL-Server für die Domaine "devdomain"

<IfDefine SSL>

<IfDefine !NOSSL>

<VirtualHost 127.0.0.2:443>

DocumentRoot "/srv/www/htdocs/Entwicklung/devdomain/trunk/"

ServerName devdomain:443

ErrorLog /var/log/apache2/error_log

TransferLog /var/log/apache2/access_log

SSLEngine on

SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL

SSLCertificateFile /etc/apache2/ssl.crt/server.crt

SSLCertificateKeyFile /etc/apache2/ssl.key/server.key

<Files ~ "\.(cgi|shtml|phtml|php3?)$">

SSLOptions +StdEnvVars

</Files>

<Directory "/srv/www/cgi-bin">

SSLOptions +StdEnvVars

</Directory>

SetEnvIf User-Agent ".*MSIE.*" \

nokeepalive ssl-unclean-shutdown \

downgrade-1.0 force-response-1.0

CustomLog /var/log/apache2/ssl_request_log ssl_combined

</VirtualHost>

</IfDefine>

</IfDefine>

Hinweise:

  • Der Host muss eine IP-Adresse erhalten - hier die lokale Loopback-Adresse.
  • Der Servername (vergl. mit /etc/hosts) wird in einer speziellen, separaten Zeile eingetragen.
  • Die IP-Adresse muss mit dem angegebenen Namen des Servers auch in der Datei "/etc/hosts" eigetragen sein !
  • Das DocumentRoot-Verzeichnis habe ich deshalb mit dem "trunk"-Zweig ausgestattet, um die Verzeichnisstruktur eines an Eclipse angebundenes SVN-Repositories zu berücksichtigen. Das kann man natürlich auch anders machen.

Nach dem Anlegen der Dateien kann man nun die neue Konfiguration nach einem "rcapache2 restart" testen. Dazu legt man im Verzeichnis

/srv/www/htdocs/Entwicklung/devdomain/trunk/

eine kleine Testdatei an oder kopiert die "index.html" aus dem Pfad "/srv/www/htdocs" dorthin. Firefox sollte beim Aufruf der Adresse "https://devdomain" keine SSL-bezogene Fehlermeldung anzeigen, sondern nur wegen des nicht vertrauenswürdigen Zertifikats warnen. Der Warnung begegnet man mit einer dauerhaften Ausnahme-Regel. Danach sollte die Test-Datei angezeigt werden. Taucht wieder Erwarten eine Meldung "ssl_error_rx_record_too_long" auf, so ist etwas an der Apache-Konfiguration faul und man muss nacharbeiten.

Das ist natürlich nur eine Ruck-Zuck-Installation eines lokalen Testservers für den Hausgebrauch auf einem PC oder Laptop. (Ein ordentlich aufgesetzter Apache2 sieht anders aus). Aber mit der obigen Konfiguration lassen sich schon bestens PHP-Programme testen.

Viel Spaß also beim PHP-Entwickeln unterwegs - und natürlich unter Linux !

Ergänzung 02.10.2012:

Eine knappe Grundinstallationsanleitung zu Apache2, MySQL, PHP (LAMP) unter Opensuse 12.1 findet man übrigens unter:
http://www.liveconfig.com/de/kb/9.html

Links

http://de.opensuse.org/Apache/SSL-Anleitung
http://de.opensuse.org/Apache
http://www.schirmacher.de/display/INFO/Apache+SSL+Zertifikat+erstellen+und+installieren
http://wiki.ubuntuusers.de/Apache/SSL
http://aktuell.de.selfhtml.org/artikel/server/apacheconf/apconf12.htm
http://de.opensuse.org/Apache/Schnellstartanleitung

Vererbung von ext3-/ext4-Gruppenrechten

Immer mal wieder fragt mich jemand, was er tun muss, damit Dateien oder Unterverzeichnisse unterhalb eines bestimmten ext3- oder ext4-Verzeichnisses auf einem Linux-System immer mit der gleichen Gruppe und (!) immer mit den gleichen Gruppen-Rechten erzeugt werden.

Problemstellung

Das Problem der Vererbung von GIDs und Gruppenrechten tritt z.B. immer dann auf, wenn mehrere Entwickler einer Gruppe auf einem Verzeichnis arbeiten und neu erzeugte Dateien auch allen anderen Benutzern der Entwicklergruppe mit gleichen Rechten zugänglich gemacht werden sollen. Und das, ohne dass man beim Erzeugen der neuen Dateien und Verzeichnisse spezielle Rechteänderungen über das "chmod"-Kommando vornehmen müsste.

Offenbar ist das Thema weniger trivial, als man meinen möchte. Denn manchmal liest man in Tutorials, dass es genügen würde, das SetGID-Bit für das betroffene Directory zu setzen. Das stimmt so leider nicht - und so mancher beginnt dann mit

"chgrp -R"     und     "chmod -R"

zu experimentieren. Was auch nicht hilft, weil das nur einmalige - wenn auch rekursive - Änderungen im betroffenen Zweig des Dateibaums herbeiführt. Das eigentliche Ziel ist aber, die richtige Gruppenzugehörigkeit und die notwendigen Rechte (meist Schreibrechte) schon beim Erzeugen einer Datei zu erhalten.

Liegen die Dateien auf einem Fremdrechner, so kann man eine Lösung über Samba erreichen. Wir wollen hier aber eine native Lösung für beschreiben.

Die richtige Antwort auf dieses Problem ist eine Kombination aus ACLs und dem SetGID-Bit.

Vorgehen

Wir nehmen zwei User eines Systems - "alpha" (uid 1001; dieser User wird der Entwicklunsgleiter) und "beta" (uid 1002). Beide seine Mitglieder der Gruppe "users" (gid 100). umask habe den Standardwert

umask 022

Was ist nun zu tun?

Schritt 1: Anlegen einer gemeinsamen Usergruppe
Als root: Anlegen einer neuen Gruppe "entwickler" (gid: 101) und Zuordnen der beiden User zu dieser Gruppe. (Unter Opensuse z.B. mit Hilfe von Yast; ansonsten mit "groupadd" und "usermod -A" - siehe die man-Seiten).

Schritt 2: Check, ob ACLs für das Filesystem aktiviert sind
Als root: Prüfe, ob das Filesystems, in dem das Verzeichnis für die Gruppenarbeit angelegt wird, mit der option "acl" gemounted wird. In der Datei "/etc/fstab" sollte sich dafür ein Eintrag der Form

/dev/myFileSystem     /myMountPoint     ext4     acl,user_xattr     1 2

finden. "myFileSystem" steht hier für das betroffene Filesystem. "/myMountPoint" steht dagegegen für das Verzeichnis, auf dem das Filesystem gemounted wird. Entscheidend ist die Option "acl".

Schritt 3: Anlegen des Verzeichnisses für die gemeinsame Entwicklungsarbeit
Als root oder Entwicklungsleiter "alpha": Anlegen des Arbeitsverzeichnisses, unter dem die gemeinsame Projektarbeit vor sich gehen soll. Z.B.:

mkdir   /myMountPoint/Entwicklung

Danach Ändern der Gruppe und der Rechte

chgrp   entwicklung     /myMountPoint/Entwicklung
chmod   775     /myMountPoint/Entwicklung

Schritt 4: Setzen des SetGID-Bits
Als Entwicklungsleiter "alpha":

chmod   g+s     /myMountPoint/Entwicklung

Von nun an erben alle Verzeichnisse und Dateien, die unterhalb des Verzeichnisses "/myMountPoint/Entwicklung" angelegt werden, die die Gruppenzugehörigkeit zur Gruppe "entwicklung".

Schritt 5: Setzen der ACL-Maske
Als Entwicklungsleiter "alpha":

cd  /myMountPoint

setfacl -m     m::rwx     Entwicklung

Diese Maske setzt die maximal möglichen Rechte für das Verzeichnis "Entwicklung".

Schritt 6: Setzen der Default-Rechte für künftige Dateien und Unterverzeichnisse
Als Entwicklungsleiter "alpha":

cd   /myMountPoint

setfacl -dm     g:entwicklung:rwx     Entwicklung

Schritt 7: Prüfen der Rechte für neue Dateien und Unterverzeichnisse
Als Gruppenmitglied "beta":

cd   /myMountPoint/Entwicklung

touch   test
ls -l
-rw-rw-r--+ 1     beta     entwicklung     0     20. Jul 20:18     test

mkdir   testdir
ls -l
drwxrwsr-x+ 2     beta     entwicklung     4096     20. Jul     21:20     testdir

touch   testdir/test2
ls -l   testdir
-rw-rw-r--+ 1     beta     entwicklung     0     20. Jul     21:22     test2

Viel Spaß nun beim Arbeiten in der Gruppe !

Links
http://wiki.ubuntuusers.de/chmod#SGID-Bit
http://wiki.ubuntuusers.de/ACL#Verzeichnisse