Im folgenden Beitrag geht es mal nicht um die Stärken und Schwächen verschiedener Webserver, sondern um die Konfiguration des Webservers für mein Spieleserver-Projekt linuxiuvat.de, das weiter in der Entstehung ist und bei dem ich fast ausschließlich auf statische Inhalte setze. Wer selbst am überlegen ist, ob er einen Ubuntu-LTS- oder Debian-Server in Zukunft aufsetzen und einen Webserver betreiben möchte, findet hier vielleicht die richtigen Informationen.
Der Artikel kann nicht die gesamte Dokumentation zu Lighttpd ersetzen. Wer aber meine kommentierte Konfigurationsdatei liest und die Abschnitte zu den verschiedenen Modulen dazu in Beziehung setzt, sollte einen guten Überblick bekommen, wie man mit ein paar Handgriffen einen ressourcenschonenden Webserver mit SSL und Authentifizierung für einen eigenen Webauftritt gestalten kann.
Warum Lighttpd?
Für ein privates Projekt mit fast ausschließlich statischen Inhalten ist Lighttpd bestens geeignet. Sein Speicherverbrauch ist äußerst gering, was ihn ideal für eine vServer-Umgebung macht. Im Regelfall zeigt mir htop nach einer Basisinstallation an, dass Lighty ungefähr 1% von den verfügbaren 225 MB des vServers für sich beansprucht und auch mit ein paar zusätzlichen Modulen steigt dieser Wert kaum an.
Lighttpd hat in der Vergangenheit bei viel größeren Projekten bewiesen, dass er sich ideal zum Ausliefern von statischen Inhalten eignet. Außerdem ist die Dokumentation ausgezeichnet und die bedingte Konfiguration empfand ich als übersichtlich und logisch.
Das weitere Angebot an freien Webservern ist wirklich groß. Einen guten Überblick verschafft z.B.
aptitude search '~shttpd'
Nginx ragt hier als weitere sehr gute Alternative heraus. Doch alle müssen sich mit der Referenz, Apache, messen lassen. Die Wahl hängt wie immer von den eigenen Ansprüchen ab, weswegen man nicht pauschal einen Webserver zum Non plus ultra erklären kann.
Wer es wirklich genügsam haben möchte, sollte sich Busybox merken, denn das bringt neben vielen UNIX-Werkzeugen auch einen eigenen Webserver mit! 🙂
Installation
aptitude install lighttpd
Wichtige Fakten
- Zentrale Konfigurationsdatei: /etc/lighttpd/lighttpd.conf
- Zusätzliche Konfiguration: /etc/lighttpd/conf-available/
- Aktivieren bzw. Deaktivieren von Modulen: lighty-enable-mod Name_des_Moduls bzw. lighty-disable-mod Name_des_Moduls. Konfigurationsdateien werden von /conf-available/ nach /conf-enabled/ verlinkt und somit aktiviert.
- Einziger Benutzer: linuxiuvat
- Standard-Webserver-Root: /var/www/server
- Ohne SSL: Symlink von /var/www/linuxiuvat.de -> /home/linuxiuvat/linuxiuvat.de
- Mit SSL: Zwei Subdomains munin.linuxiuvat.de und stats.linuxiuvat.de
- Standardmodule: mod_access, mod_alias, mod_compress, mod_redirect, mod_expire
- Zusätzliche Module: mod_ssl, mod_cgi, mod_auth, mod_status, mod_accesslog
Meine lighttpd.conf
Meine eigene lighttpd.conf in kommentierter Fassung. Fragen, Anregungen oder Kritik bitte jederzeit in die Kommentare posten.
Konfiguration
Virtuelle Hosts
Um virtuelle Hosts zu verwalten, bietet Lighttpd verschiedene Möglichkeiten an. Für größere Projekte empfiehlt sich das schlichte und effektive mod_simple_vhost oder das verbesserte mod_evhost. Wer selbst zum Webhoster werden möchte und zahlreiche Domains verwalten muss, sollte sich die datenbankgestützte und programmierbare Lösung namens mod_mysql_vhost genauer anschauen.
Für kleine Projekte mit einer überschaubaren Anzahl von Domains und Subdomains ist aber Lightys bedingte Konfiguration vollkommen ausreichend.
Hauptseite ohne SSL
Die Inhalte werden auf der Hauptseite unverschlüsselt ausgeliefert, wozu die $SERVER["socket"]-Bedingung Anwendung findet. Das Dokumenten-Wurzelverzeichnis wird in das Home-Verzeichnis des Benutzers linuxiuvat verlinkt. Neue Inhalte werden dort eingestellt. Die Host-Bedingung prüft, ob entweder www.linuxiuvat.de oder nur linuxiuvat.de aufgerufen wurde und führt danach alle Anweisungen im Konfigurationsblock aus. Zusätzlich zur Datei access.log, die später noch vorgestellt wird, ist hier noch der Pfad zu einer angepassten 404-Fehlerseite zu sehen, sowie der Pfad zur error.log.
$SERVER["socket"] == "134.0.24.218:80" {
$HTTP["host"] =~ "^(www.)?linuxiuvat.de$" {
server.document-root = "/var/www/linuxiuvat.de"
server.error-handler-404 = "/e404.htm"
accesslog.filename = "/var/log/lighttpd/linuxiuvat.de/access.log"
server.errorlog = "/var/log/lighttpd/linuxiuvat.de/error.log"
}
}
Mit der folgenden Bedingung lässt sich verhindern, dass die Webseite direkt über die Eingabe der IP-Adresse aufgerufen werden kann, wobei das Modul mod_access Anwendung findet.
$HTTP["host"] =~ "134.0.24.218" {
url.access-deny = ( "" )
}
mod_cgi
Die einzige CGI-Datei, die ich z.Z. benutze, befindet sich im Verzeichnis /cgi-bin/. Sie kommt zum Einsatz, wenn jemand einen Kommentar in meinem mit Chronicle erzeugten Newsblog hinterlassen möchte.
Das Modul wird mit
lighty-enable-mod cgi
aktiviert.
$HTTP["url"] =~ "^/cgi-bin/" {
cgi.assign = ( "" => "/usr/bin/perl" )
}
mod_accesslog
Mit dem Modul mod_accesslog werden alle Anfragen an den Webserver mitgeloggt. Aktiviert wird es mit
lighty-enable-mod accesslog
1. /etc/lighttpd/conf-available/10-accesslog
server.modules += ( "mod_accesslog" )
accesslog.filename = "/var/log/lighttpd/access.log"
Damit die Datei access.log für jeden Host einzeln angelegt wird, kann man sie wie bei Lighttpd üblich in eine bedingte Konfiguration einbinden.
accesslog.filename = "/var/log/lighttpd/linuxiuvat.de/access.log"
mod_expire
Das Modul mod_expire hilft dabei statische Inhalte aggressiv zu cachen, d.h. Bilder, CSS- und Javascriptdateien erhalten bei der Übertragung an den Webbrowser ein Verfallsdatum bis zu dem der Browser die Dateien aus seinem Cache lädt anstatt sie neu vom Server anzufordern. Das spart Bandbreite und führt zu schnelleren Ladezeiten.
Aktivieren mit
lighty-enable-mod expire
Die Bedingung lässt sich z.B. so schreiben, dass nur Dateien mit einer bestimmten Dateiendung zwischengespeichert werden sollen. In diesem Fall beträgt die Verfallszeit sieben Tage vom ersten Aufruf an.
$HTTP["url"] =~ ".(jpg|gif|png|css|js)$" {
expire.url = ( "" => "access 7 days" )
}
Natürlich kann man die Bedingung auch so schreiben, dass die Dateien nur aus zwei verschiedenen Verzeichnissen gecached werden sollen.
$HTTP["url"] =~ "^/img/|/stats/oa/icons/" {
expire.url = ("" => "access 7 days")
}
Mit Hilfe des Firefox-Plugins Live-HTTP-Headers oder mit curl kann man schnell feststellen, ob tatsächlich der richtige HTTP-Header verschickt wird.
curl -I http://linuxiuvat.de/img/openarena.jpg
Quelle: Forum von nixcraft.com.
mod_ssl
Zum Aktivieren einer verschlüsselten SSL-Verbindung per HTTPS genügt wieder ein
lighty-enable-mod ssl
Das SSL-Zertifikat habe ich mir selbst ausgestellt, was ich für kleine Projekte, bei denen man der einzige Betrachter der verschlüsselten Seite ist auch empfehlen kann. Wer jedoch eine Shop-Seite zusammenzimmert sollte seine Kunden wenn möglich nicht mit einer Warnmeldung im Browser verschrecken und ein "richtiges" Zertifikat kaufen. 🙂
Als Superuser:
openssl req -new -x509 -keyout linuxiuvat.de.pem -out linuxiuvat.de.pem -days 365 -nodes
Die Pem-Datei wurde nach /etc/lighttpd/ssl/linuxiuvat.de/linuxiuvat.de.pem kopiert und die Dateirechte aus Sicherheitsgründen mit chmod 400 eingeschränkt.
1. /etc/lighttpd/conf-available/10-ssl.conf
Ich habe die Konfiguration getrennt und den Teil, der sich um die SSL-Engine selbst dreht in der 10-ssl.conf belassen. Wichtig ist hier nur die richtige Adresse für den Socket einzutragen, also eure IP-Adresse und den Port des Webservers. Alternativ kann man auch :443 oder 0.0.0.0:443 schreiben, wenn man möchte, dass der Webserver auf allen Interfaces Anfragen entgegennimmt. Die Schreibweise muss aber überall die gleiche sein.
$SERVER["socket"] == "134.0.24.218:443" {
ssl.engine = "enable"
ssl.pemfile = "/etc/lighttpd/ssl/linuxiuvat.de/linuxiuvat.de.pem"
ssl.cipher-list = "ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM"
ssl.honor-cipher-order = "enable"
}
2. /etc/lighttpd/lighttpd.conf
Durch die bedingte Konfiguration sind die beiden Subdomains munin.linuxiuvat.de und stats.linuxiuvat.de nur über HTTPS zu erreichen. Es wurde jeweils das Dokumenten-Wurzelverzeichnis geändert, so dass es auf den Standardausgabepfad von Munin und Awffull zeigt. Die Statusseite ist über https://munin.linuxiuvat.de/status zu erreichen und wird durch das Modul mod_status aktiviert.
$SERVER["socket"] == "134.0.24.218:443" {
$HTTP["host"] =~ "(^|.)munin.linuxiuvat.de$" {
server.document-root = "/var/cache/munin/www"
status.status-url = "/status"
}
$HTTP["host"] =~ "(^|.)stats.linuxiuvat.de$" {
server.document-root = "/var/www/awffull/"
}
}
mod_auth
Das Authentifizierungsmodul ist notwendig, um den Zugriff auf einzelne Verzeichnisse einzuschränken. In meinem Fall genügt es, dass ich die Munin- und Awffull-Statistiken anschauen kann. Das Modul mod_auth wird mit
lighty-enable-mod auth
aktiviert. Es gibt zwei verschiedene Methoden sich zu authentifizieren - Basic und Digest. Je nach Methode existieren unterschiedliche Backends, wie die Passwörter aufgebaut und gespeichert werden. Ich habe mich für Digest und htdigest entschieden, wodurch das Passwort nicht in Klartext übertragen wird und als MD5-Hash abgespeichert wird. Alle Methoden sind dennoch nur dann wirklich sicher, wenn das Passwort über eine verschlüsselte Verbindung übertragen wird.
1. /etc/lighttpd/conf-available/10-auth.conf
server.modules += ( "mod_auth" )
auth.backend = "htdigest"
auth.backend.htdigest.userfile = "/etc/lighttpd/.passwd"
auth.debug = 2
$HTTP["host"] =~ "(^|.)munin.linuxiuvat.de$" {
auth.require = ( "" =>
(
"method" => "digest",
"realm" => "privat",
"require" => "valid-user"
),
)
}
Auth.debug=2 ist sehr gesprächig, aber hilfreich, wenn man mehr über erfolgreiche und nicht erfolgreiche Loginversuche wissen möchte. Die versteckte Passwortdatei .passwd mit den benötigten Inhalten lässt sich wie folgt erstellen. Der "Realm" kann beliebig gewählt werden.
htdigest -c /etc/lighttpd/.passwd 'privat' Bob
Das Programm htdigest befindet sich im Paket apache2-utils und wird nur für diese eine Aufgabe benötigt. Danach hat nur noch der Benutzer Bob mit dem zuvor eingegebenen Passwort Zugriff auf das Verzeichnis, wobei die gesamte Verbindung gegenüber Dritten per SSL abgesichert ist.
mod_status
Mit mod_status gibt es Auskunft über Uptime, Anfragen pro Sekunde und aktive Verbindungen, kurz zusammengefasst also über den Status des Webservers. Die HTML-Seite ist schlicht und übersichtlich. Um die Daten per Munin mit einem Graphen zu visualisieren kann man noch ein ?auto an die URL anhängen, wodurch die Ausgabe als Text dargestellt wird. Hierzu in einem anderen Artikel mehr.
Das Modul wird mit
lighty-enable-mod status
aktiviert. Die Zeile
status.status-url = "/status"
muss wie in der Konfiguration gezeigt innerhalb der bedingten Host-Konfiguration eingefügt werden.
Was sonst noch?
Lighttpd bietet noch weit mehr Möglichkeiten und Module. Das sind zur Zeit aber alle, die ich für mein Projekt und dieses Beispiel verwende. Man sollte im Hinterkopf noch mod_evasive und die Variablen
server.kbytes-per-second
connection.kbytes-per-second
behalten, wenn man den Traffic auf dem Webserver besser steuern möchte.
Für Lighttpd gilt: Fast jedes Problem lässt sich mit der bedingten Konfiguration lösen.
Links