Raspberry Pi: Webserver einrichten

Prof. Jürgen Plate

Raspberry Pi: Webserver einrichten

Der erste Webserver für Linux kam von der europäischen Forschungseinrichtung CERN, wo ja auch Tim Berners-Lee das World Wide Web erfunden hat. Schon bald gab es weitere Server, darunter einen Ableger der CERN-Serversoftware, der "Apache" genannte wurde ("a patchy CERN Server"). Inzwischen gibt es nicht nur den Apachen für Linux, sonderen etliche andere - obwohn der Webindianer immer noch mit Abstand der verbreitetste Server ist. Natürlich gibt es ihn auch für den Raspberry Pi.

Aber der Apache kann viel mehr als man normalerweise braucht und weil der RasPi von der Leistung her eher etwas schwach auf der Brust ist, empfehle ich den Light HTTPD (lighttpd), der nicht so stark aufträgt und relativ einfach zu konfigurieren ist. Jedoch unterstützt der Webserver per Voreinstellung weder CGI-Scripte noch PHP. Er liefert also nur statische HTML-Seiten aus - das aber recht flott. Alles Wetere muss per Konfigurations-Datei eingerichtet werden.

Installation von lighttpd und php5-cgi

Vor der Konfiguration kommt aber die Installation. Dabei holen Sie sich auch gleich PHP:

sudo su                            # root werden, damit fuer alles Weitere 
                                   # nicht immer sudo noetig ist
apt-get update                     # datenbasis aktualisieren
apt-get install lighttpd           # Webserver installieren
apt-get install php5-cgi           # PHP installieren
Der Pfad zum Konfigurationsverzeichnis ist /etc/lighttpd/. Dort finden Sie die Konfigurations-Datei lighttpd.conf und zwei Verzeichnisse, conf-available und conf-enabled. In ersterem sind kleine Konfigurationsdateien für bestimmte fest umrissene Zwecke und im zweiten Verzeichnis sind symbolische Links auf die aktuell verwendeten Dateien. Benötigt werden 10-cgi.conf und 10-fastcgi.conf. Wer mit dem ln-Kommando auf Kriegsfuß steht, kann sie mit den folgenden Kommandos aktivieren:
lighttpd-enable-mod cgi
lighttpd-enable-mod fastcgi
Übrigens ist lighttpd-enable-mod nur ein Symlink auf lighty-enable-mod.

Anpassen der Konfigurationsdateien

Nach diesen Vorarbeiten sind noch einige Änderungen an den Konfigurationsdateien erforderlich. Zuerst richten Sie sich aber die Umgebung für Ihre Webseite ein. Bei der Installation wird schon das Verzeichnis /var/www/ eingerichtet. Wenn CGI-Scripte verwendet werden sollen, sollte eine weitere Ebene eingezogen werden:

Dann kann auch gleich die bei der Installation erzeugte Datei nach htdocs wandern und die Verzeichnisse werden dem User pi übertragen:
cd /var/www
mkdir htdocs
mkdir cgi-bin
mv index.lighttpd.html htdocs/index.html
chown -R pi.pi /var/www

Nun werden die Konfigurationsdateien angepasst. Zuerst die Datei 10-cgi.conf: Hier müssen "mod_cgi", der Pfad zum Verzeichnis cgi-bin sowie die Dateiendungen und Pfade der Script-Programme eingetragen werden. Die Datei hat dann folgenden Inhalt:

# /usr/share/doc/lighttpd/cgi.txt

server.modules += ( "mod_cgi" )

alias.url += ( "/cgi-bin/" => "/var/www/cgi-bin/" )
$HTTP["url"] =~ "/cgi-bin/" {
        cgi.assign = ( 
              ".pl" => "/usr/bin/perl", 
              ".py" => "/usr/bin/python", 
              ".cgi" => "/bin/bash", 
        )
}

## Warning this represents a security risk, as it allow to execute any file
## with a .pl/.py even outside of /usr/lib/cgi-bin.
#
#cgi.assign      = (
#	".pl"  => "/usr/bin/perl",
#	".py"  => "/usr/bin/python",
#)
Im zweiten Schritt wird die Datei 10-fastcgi.conf erweitert. Hier wird die Info für den fastcgi.server hinzugefügt, so dass die Datei anschließend folgenden Inhalt besitzt:
# /usr/share/doc/lighttpd/fastcgi.txt.gz

server.modules += ( "mod_fastcgi" )

fastcgi.server = ( ".php" => ((
                     "bin-path" => "/usr/bin/php-cgi",
                     "socket" => "/tmp/php.socket"
                 )))

Im dritten Schritt wird die Haupt-Konfigurationsadatei geändert. Hier wird die "server.document-root" von /var/www auf /var/www/htdocs korrigiert. Die Datei hat danach folgenden Inhalt:
server.modules = (
      "mod_access",
      "mod_alias",
      "mod_compress",
      "mod_redirect",
#     "mod_rewrite",
)

server.document-root        = "/var/www/htdocs"
server.upload-dirs          = ( "/var/cache/lighttpd/uploads" )
server.errorlog             = "/var/log/lighttpd/error.log"
server.pid-file             = "/var/run/lighttpd.pid"
server.username             = "www-data"
server.groupname            = "www-data"
server.port                 = 80


index-file.names            = ( "index.php", "index.html", "index.lighttpd.html" )
url.access-deny             = ( "~", ".inc" )
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )

compress.cache-dir          = "/var/cache/lighttpd/compress/"
compress.filetype           = ( "application/javascript", "text/css", "text/html", "text/plain" )

# default listening port for IPv6 falls back to the IPv4 port
include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
include_shell "/usr/share/lighttpd/create-mime.assign.pl"
include_shell "/usr/share/lighttpd/include-conf-enabled.pl"

Das war es fast schon. Jetzt muss der lighttpd nur noch die Änderungen der Konfiguration übernehmen. Das erreichen Sie mit dem Kommando:

/etc/init.d/lighttpd force-reload

Test

Der erste Test ist ganz einfach: Es wird der RasPi mit dem Browser angesprochen und die Datei index.html abgerufen. Sie gibt einige Basisinfos über den Webserver wieder.

Für PHP schreiben Sie sich eine kleine PHP-Datei, zum Beispiel mit folgendem Inhalt:

<?PHP
print '<html><body><h1>PHP works also!</h1>
<p>This is the default PHP web page for this server.</p>
';

phpinfo();

print '</body></html>';
?>

Auch für den CGI-Test wird eine Datei erstellt, diesmal im Verzeichnis cgi-bin. Für den Test reicht ein einfaches Shellscript mit folgendem Inhalt. Wichtig ist hier, dass Sie das Script mittels chmod +x index.cgi ausführbar machen, sonst gibt es nur den Fehler 500 (Internal Server Error) zu sehen.

#/bin/bash
cat << EOF
Content-type: text/html

<html><body><h1>CGI works also!</h1>
<p>This is the default CGI web page for this server.</p>
</body></html>

Jetzt können Sie gegebenefalls noch Perl- und Python-Scripte nach dem gleichen Schema testen. Auf alle Fälle ist nach erfolgreichem Test der Webserver einsatzbereit.

Besonderheiten der Web-Programmierung

Der Webserver läuft mit einer eigenen Benutzerkennung, die meist stark eingeschränkt ist. In der Regel ist dies der User www-data. Deshalb müssen unter Anderem alle Dateien, auf die per CGI- oder PHP-Script geschrieben werden soll, dem User www-data gehören und die richtigen Zugriffsrechte besitzen. Der Tipp, den man oft im Web findet, die Zugriffsrechte auf 777 (alle dürfen alles) zu setzen, ist da nicht nur unsicherer, sondern zeigt auch, dass der Tippgeber die Benutzerverwaltung von Linux nicht duchschaut hat.

Achtung: Trotz des Kommandos chmod 666 ... wird kein Zugriffsrecht für others auf die GPIO-Pins zugelassen. Wenn der Benutzeraccount www-data auf die GPIO-Pins zugreifen soll, muss der Benutzer zusätzlich in die Gruppe gpio eingetragen werden:
sudo usermod -a -G gpio www-data

Beim Durchgriff auf das System, etwa bei den GPIO-Pins, kann es also Probleme mit PHP und dem User www-data geben. Manchmal hilft dann nur noch, ein kleines C-Programm zu schreiben, das mit Root-Rechten läuft (bei dem das SUID-Bit gesetzt ist → chmod u+s xxxx). Austesten kann man das gut, wenn man die Identität des Users www-data annimmt (z. B. als Root durch su - www-data) und dann die Programme oder Skripte unter dieser Userkennung ausführt.

Oft werden Fehler auch nicht immer im Browser angezeigt (das Script stürzt einfach wortlos ab). Wenn etwas nicht klappt, hilft oft ein Blick in die Logfiles, bei Light Httpd finden Sie die Fehlermeldungen in /var/log/lighttp/error.log. Aber auch die anderen Logfiles geben oft wertvolle Hinweise.

Je nach PHP-Installation und Konfiguration werden meist nur bestimmte Typen von Fehlermeldungen angezeigt. Die Wahl der Typen wird durch die Funktion error_reporting und der dazugehörigen Konfiguration in der Datei php.ini bestimmt. Um alle Fehlermeldungen zu aktivieren setzt man den Wert für error_reporting im Programm auf E_ALL. Zusätzlich sorgt die Einstellung von display_errors, ob überhaupt Fehlermeldungen angezeigt werden sollen. Während der Programmentwicklung wird diese Einstellung aktiviert, beim laufenden Betrieb jedoch deaktiviert. An den Programmanfang kommen deshalb die beiden Zeilen:

error_reporting(E_ALL);
ini_set('display_errors', 1);

Der Light Httpd kennt leider keine Steuerung über die Datei .htaccess um Passwortschutz oder spezielle Features einzustellen; die Konfiguration erfolgt ausschließlich über die Konfigurationsdateien des lighttpd. Näheres dazu finden Sie in der Dokumentation des Serverprogramms. Jedoch will ich Ihnen eine Konfigurationsmöglichkeit nicht vorenthalten. Die Einstellung von individuellen Fehlermeldungen erreichen Sie über den Eintrag

server.error-handler-xxx = "<Dateiname>"
wobei "xxx" die Fehlernummer ist (meist reichen Einträge für 401, 402, 403, 404 und 500). Zum Beispiel für den Fehler "Seite nicht gefunden":
server.error-handler-404 = "/error.php"

Das Demo-Programm zum Herunterladen (nach dem Herunterladen die Endung ".txt" entfernen) zeigt die prinzipiellen Anwendung von PHP zum Ansteuern der GPIO-Pins, wobei die Initialisierung der Pins vorab bereits erfolgt sein muss (wie unter RasPi_GPIO.html gezeigt). Ebenso wird kurz erklärt, wie man aus PHP heraus andere Programme aufruft und deren Ausgabe weiterverarbeitet.


Copyright © Hochschule München, FK 04, Prof. Jürgen Plate
Letzte Aktualisierung: