Skript-gesteuerte Downloads mit Mod-Xsendfile für Apache2 anbieten

Schneller senden

Downloads serverseitig mit Skriptsprachen abzusichern, ist ein einfacher aber langsamer Weg. Mod-Xsendfile für Apache2 verbindet die Vorteile von Skriptsprachen und schnellen Downloads statischer Dateien.

Ein klassisches Problem der Webentwicklung ist die zugangsgeschützte Auslieferung von Dateien. Lange konnte diese Aufgabe durch Htaccess-artige Zugriffskontrollen direkt vom Webserver abgewickelt werden. Mit den zunehmend komplexer werdenden Web-Frameworks und der konsequenten Anbindung der Nutzerverwaltung an Datenbanken, der Abwicklung von Transaktionen über Zahlungssysteme und so weiter jedoch ist es notwendig, die Zugriffe auf geschützte Dateibereiche direkt in Sprachen wie PHP und Rails/Ruby abzubilden, um komplexe Rechteprüfungen zu ermöglichen.

Skriptsprachen bieten die Möglichkeit, nach der Prüfung von Zugriffsrechten den Inhalt einer außerhalb des Web-Roots liegenden Datei als Stream an den Webserver zu senden, der diesen dann an den Browser des Nutzers weiterleitet. Diese flexible Methode ist bequem in die bestehende Programmierung integrierbar und verhindert den direkten Zugriff auf Dateien oder das Deep-Linking. Listing 1 zeigt ein typisches Beispiel in PHP, dass nach Prüfung einer fiktiven Bedingung die einfache »readfile« -Methode nutzt, um eine Datei als Download auszuliefern, nachdem für den Download notwendige Header gesetzt wurden.

Listing 1

readfile() mit PHP

<?php
// $datei enthält kompletten Pfad in der Form /pfad/zu/dateiname
// $dateiname enthält nur den Namen der Datei
// $bedingung kann der Status des Logins o.ä. sein
if ($bedingung==true) {
        // setze Header für problemlosen Download
        header ('Content-Type: application/octet-stream');
        header ('Content-Length: '.filesize($datei));
        header ('Content-Disposition: attachment; filename='.$dateiname );
        // beginne mit Ausgabe der Datei
        readfile ($datei);
        exit;
}
?>

Spürbar nachteilig wirkt sich diese Methode jedoch auf die Performance aus: Skriptsprachen und Applikationen wie Rails-Mongrel können empfindliche Last verursachen oder vollständig blockiert werden. Doch das muss nicht sein. Am Beispiel von Apache2 und Mod-Xsendfile [1] wird daher im Folgenden erklärt, wie man den Transfer binärer Daten trotz skriptbarem Zugangsschutz direkt vom Webserver abwickeln lässt.

Das hierfür genutzte Modul ist die Portierung eines bereits länger verfügbaren Features des Moduls »mod_fastgi« für den schlanken Webserver Lighttpd [2]. Es basiert auf der einfachen Idee, Webserver und Skriptinterpreter quasi rückwärts miteinander sprechen zu lassen. Normalerweise werden per Skript Request-Daten und Servervariablen ausgewertet – der Interpreter ist die letzte Stufe der Datenauswertung. Mit Mod-Xsendfile wertet der Webserver die Rückmeldung der Skriptsprache aus. Es wird dabei nicht mehr gemacht, als die vom Skriptinterpreter gesendeten Header nach dem Muster »X-Sendfile: Dateiname« zu durchsuchen. Bei einem Treffer verhindert der Server die direkte Auslieferung der Skriptrückmeldung und versucht stattdessen, die im Header angegebene Datei auszuliefern (Abbildung 1). Das Modul ermöglicht damit eine bequeme, skriptbasierte Zugriffsverwaltung, zugleich aber den schnellen Datentransfer direkt per Webserver.

Weitere Vorteile

Ebenso hilfreich wie die Entlastung des Skript-Interpreters beziehungsweise Applikationsservers ist die Vereinfachung des Cachings. Skriptsprachen verhindern in der Regel das Caching durch setzen von No-Caching- bzw. Entfernen von Caching-Headern. Es handelt sich schließlich um dynamische Webinhalte und so sollen Proxyserver und Browser von einer Zwischenspeicherung der Daten abgehalten werden. Beim Bereitstellen statischer Daten wie Downloads und Bildergalerien kann diese Caching-Behinderung nachteilig sein, da unnötiger Traffic verursacht wird. Im Fall von Mod-Xsendfile entspannt sich die Situation durch das Senden von Headern wie »Last-Modified« , die das Cachen statischer Inhalte trotz dynamischer Auslieferung ermöglichen. Zwar können entsprechende Caching-Header auch manuell in einem Skript gesetzt werden, jedoch ist die Kombination aus Header und Auslieferung über sendfile/mmap ein praktisches Zusammenspiel, das außerdem weniger Zeilen Quelltext erfordert.

Hervorzuheben ist auch die Möglichkeit, performante Download-Zähler zu betreiben. Auf Seiten mit größeren Download-Archiven reichen die üblichen Apache-Statistiken oft nicht und eine einfache Zählung von Downloads über Datenbank-basierte Auswertungen ist wünschenswert. Während man bisher den Vorteil einer Zählung mit dem Nachteil der damit einhergehenden Performance-Einbuße durch skriptbasierte-Downloads abwägen musste, entfällt dieses Dilemma mit Mod-Xsendfile vollständig.

Neben dem performanten Senden von Daten über die optimierten Apache-eigenen Methoden bietet Mod-Xsendfile damit einen deutlichen Funktionszugewinn, der neben einem vereinfachten Caching auch skriptbare Download-Zähler und ähnliches vereinfacht. All dies war natürlich auch vor Mod-Xsendfile möglich, jedoch ist die Kombination

Installation

Derzeit muss Mod-Xsendfile auf den meisten Linux-Derivaten noch direkt aus den Quellen übersetzt und installiert werden. Dank "apxs", dem "APache eXtenSion tool" [3] ist diese Aufgabe sehr schnell zu erledigen. Je nach Distribution wird »apxs« , das gelegentlich auch »apxs2« genannt wird, bereits mit dem Apache-Webserver installiert oder muss nachinstalliert werden. Unter Debian Etch wird dies über »aptitude install apache2-prefork-dev« beziehungsweise »aptitude install apache2-threaded-dev« – je nach installierter Apache-Variante erledigt.

Die eigentliche Installation des Moduls beginnt mit den üblichen Schritten Quellen laden, entpacken, ins Verzeichnis wechseln. Statt der klassischen configure/make/make install Triade wird nun »apxs« beziehungsweise »apxs2« aufgerufen und angewiesen, das Modul zu kompilieren (»-c« ), installieren (»-i« ) und aktivieren (»-a« ). Die folgenden Zeilen zeigen die Installation unter Debian Etch, wobei das Listing nahezu unverändert auf die meisten anderen Distributionen übertragbar sein sollte. Wichtig ist vor allen, ob das Apache Extension Tool »apxs« oder »apxs2« heißt.

wget http://tn123.ath.cx/mod_xsendfile/↩
mod_xsendfile-0.9.tar.gz
tar xzf mod_xsendfile-0.9.tar.gz
cd mod_xsendfile-0.9
apxs2 -cia mod_xsendfile.c

Wie viele Apache-Module muss Mod-Xsendfile in einem Kontext aktiviert werden. Das Modul ermöglicht die Konfiguration global auf Server-Ebene, innerhalb eines virtuellen Hosts oder in einer.htacces-Datei. Die Direktive »XSendFile on« weist das Modul an, »X-Sendfil« e-Header zu verarbeiten. Standardmäßig erlaubt Mod-Xsendfile nur die Auslieferung von Daten, die unterhalb der aufgerufenen Adresse liegen. Da aber gerade die Auslieferung von Dateien interessant ist, die sich vollständig außerhalb des Web-Roots befinden, kann diese Sicherheitsprüfung in den selben Kontexten wie eben beschrieben deaktiviert und die Auslieferung auch höher liegender Dateien mittels »XSendFileAllowAbove on« gestattet werden.

Ähnliche Artikel

comments powered by Disqus