Squid als Reverse-Proxy

13.01.2005 von THOMAS WOELFER 
Setzt man den Squid-Cache als Reverse-Proxy ein, kann man Traffic und Bandbreite sparen sowie die Geschwindigkeit des eigenen Webservers enorm steigern. Doch nur wenige machen von dieser nützlichen Funktion Gebrauch.

Der Squid-Cache ist als Open-Source-Lösung schon seit Jahren beliebt und bekannt. Und obwohl auch die Reverse-Proxy-Funktion bereits vor langer Zeit implementiert wurde, nutzt man sie nur selten. Dabei wäre ein Reverse-Proxy für Webseiten-Betreiber ein echter Glücksgriff.

Im Normalfall wird der Squid als Webcache in Firmen oder als beschleunigender Proxy in kleinen LANs mit langsamen Internet-Zugängen eingesetzt. Wie so oft bei guten Ideen, so ist auch die dem Webcache des Squid zu Grunde liegende Idee eigentlich ganz einfach: Auf der Innenseite des eigenen LAN installiert man vor dem Internet-Zugang einen Rechner mit Squid als Proxy für Webanfragen - oder auch für ftp und andere vom Squid unterstützte Protokolle.

Den Internet-Anwendungsprogrammen im LAN weist man dann den Squid-Rechner als Proxy für die vorgesehenen Protokolle zu. Die Browser werden zum Beispiel so konfiguriert, dass sie http-Anfragen an den Squid anstatt an das Internet-Gateway des LAN senden.

Der Squid nimmt diese Anfragen an und liefert die Antwort entweder aus dem eigenen Cache aus, oder er holt sie von der ursprünglichen URL, falls er die Seite noch nicht kennt oder der Cache-Eintrag veraltet ist. Daraus resultiert zum einen, dass Anfragen von Clients aus dem LAN deutlich schneller beantwortet werden, wenn die gleiche Seite bereits angefordert wurde. Zum anderen spart man Bandbreite und Traffic nach außen.

Der Squid als Reverse-Proxy

Das Interessante am Squid ist, dass man das Programm auch für Client-Requests von der anderen Seite prima einsetzen kann: Der Squid fungiert auch als Reverse-Proxy. Das hebt Squid von anderen Webproxies deutlich ab: So kann der ISA Server 2004 von Microsoft zwar auch als Reverse-Proxy eingesetzt werden, allerdings mit im Vergleich zum Squid eher mäßiger Flexibilität.

Die Installation des Reverse-Proxy ist dabei ähnlich klar strukturiert wie die des normal operierenden Proxys: Der Webserver-Betreiber installiert vor dem eigentlichen Webserver einen Squid. Die DNS-Einträge für das Webangebot sind so zu verändern, dass sie nicht länger auf den Webserver selbst, sondern auf den Squid-Rechner verweisen. Client-Anfragen landen also auf dem Squid, anstatt auf dem Webserver selbst.

Die Vorteile dieser Konfiguration sind jedoch nicht so offensichtlich, wie das bei einem normalen Webcache der Fall ist. Trotzdem macht sich die Nutzung des Squid dramatisch bemerkbar - auch in diesem Nutzungs-Szenario gibt es zwei wichtige Auswirkungen. Welche davon wichtiger ist, hängt von der Art des Webauftritts ab.

Vorteil 1: Weniger Last auf dem Webserver

Der als Reverse-Proxy konfigurierte Squid nimmt alle Client-Anfragen entgegen. Mit dieser Anfrage verfährt er im Grunde genauso wie ein normaler Proxy: Er überprüft, ob er für diese Anfrage bereits eine Antwort kennt. Ist die Antwort noch nicht veraltet, dann liefert er sie direkt aus - es gibt keinen weiteren Round-Trip zum eigentlichen Webserver. Nur wenn die Antwort veraltet ist oder nicht vorliegt, leitet er die Anfrage an den eigentlichen Webserver weiter. Daraus resultiert eine dramatisch reduzierte Anzahl von Anfragen an den Webserver. Das ist auf den ersten Blick nichts besonders Aufregendes: Schließlich spart man ja insgesamt keine Anfragen, denn der Squid muss diese ja weiterhin entgegennehmen und abarbeiten.

Aber: Der Squid kann eine Anfrage um ein Vielfaches schneller beantworten als der Webserver. Das trifft im Besonderen auf Anfragen zu, die mit Hilfe von Programmen oder Scripts (PHP, CGI, ASP, ...) beantwortet werden. Beim Squid reicht im Wesentlichen ein Lookup in einer großen Hash-Tabelle. Der Webserver dagegen benötigt mindestens einen Festplattenzugriff. Er stattet die geladene Datei mit zusätzlichen http-Header-Informationen aus, bevor er sie ausliefert.

In der Praxis wird der Webserver obendrein einen eigenen Prozess (oder Thread) starten, um die Datei vor der Auslieferung weiter zu bearbeiten: Dort läuft dann zum Beispiel die PHP-Engine, um die Seite dynamisch zusammenzubauen, im schlimmsten Fall aus den Ergebnissen einer Datenbankabfrage. Dieser Verbrauch an CPU-Leistung und Arbeitsspeicher macht sich natürlich deutlich bemerkbar.

Der Squid hingegen braucht nur einen einzelnen Prozess, mit dessen Hilfe er seinen Cache durchsucht: Während ein typischer Webserver-Zugriff mit einfachen Tools wie top (unter Unix) bereits zu bemerken ist, bleibt die Belastung durch den Squid praktisch bei null.

Lange Rede, kurzer Sinn: Der Einsatz des Squid spart erheblich Rechenleistung auf Web- und Datenbank-Servern. Man kann also mit der gleichen Webserver-Hardware deutlich mehr Benutzer versorgen als ohne Squid. Und dies wiederum erspart zusätzlich zeitaufwendige Wartungsarbeiten.

Vorteil 2: Entkopplung

Der Webserver selbst wird mit großer Sicherheit immer mit anderen Rechnern in einer DMZ laufen: Mindestens ein Datenbank-Server, und vermutlich auch noch Backup-Hardware, wird sich in dieser DMZ befinden müssen.

Das bedeutet nahezu zwangsläufig, dass Datenbank- und Webserver räumlich nicht sonderlich weit voneinander getrennt werden dürfen: Zugriffe des Webservers auf den Datenbank-Server will man sicherlich mit mindestens 100 Mbit/s ermöglichen, was bei Verbindungen über das Internet hohe Kosten verursachen würde. Das bedeutet letztlich, dass die gesamte Hardware des Webauftritts in unmittelbarer räumlicher Nähe zueinander aufzustellen ist.

Für Squid gilt dies jedoch nicht. Zwar ist es schön, wenn auch er eine schnelle Verbindung zum Webserver hat - doch da nur ein Bruchteil der Daten tatsächlich zwischen Squid und Webserver transportiert werden müssen, ist das nicht unbedingt erforderlich.

Das bedeutet, dass der Squid tatsächlich an einer anderen Stelle untergebracht werden kann als der Webserver - und damit lassen sich unter Umständen erneut Leitungskosten sparen. Es ist sehr viel einfacher, mit einem einzelnen Squid-Server umzuziehen, als mit der ganzen DMZ. Daher fällt es auch deutlich leichter, einen in Sachen Bandbreite und Traffic möglichst preisgünstigen Platz für den Squid zu finden. Die DMZ dagegen bringt man an einem organisatorisch möglichst günstigen Ort unter. Diese Flexibilität ist ohne Squid nicht gegeben.

Squid entkoppelt das DMZ vom Internet

Zu den bisher genannten Fakten kommt noch eine weitere Einzelheit, die die Parameter des Squid betreffen: Steht der Squid in direkter räumlicher Nähe zum Webserver, so wird man ihn so konfigurieren, dass auf dem Squid möglichst überhaupt keine Festplattenzugriffe stattfinden. Das Programm soll dann Anfragen entweder direkt aus dem RAM beantworten, oder aber den schnell zu erreichenden Webserver bemühen.

Da das eigentliche Einsatzgebiet des Squid aber ein Webcache ist, kann das Programm Objekte natürlich auch auf der Festplatte auslagern. Ist der Squid also vom Webserver räumlich getrennt, so empfiehlt es sich, Objekte möglichst lange auf der Festplatte vorrätig zu halten. Kommt die Webseite mit nur wenigen kurzlebigen Objekten aus, dann ist es in der Praxis auch möglich, den Squid in einem Rechenzentrum mit hoher Bandbreite unterzubringen. Für die Anbindung des Webservers selbst reicht in diesem Fall durchaus eine Sparleitung.

Eine Beispiel-Site mit Squid

Auf einer vom Autor dieses Artikels betreuten Website mit ein paar Millionen Seitenabrufen pro Monat lässt sich das Resultat durch den Einsatz von Squid deutlich erkennen. Hierzu einige Zahlen:

Der Squid weist im Vergleich zum Webserver etwa die fünffache Menge an ausgehendem Traffic auf - ein Großteil kann also aus dem Proxy-Cache ausgeliefert werden. Bei in etwa vergleichbarer Hardware hat der Webserver trotzdem fast immer eine Auslastung von ca. 50 Prozent, während die Auslastung des Proxy praktisch bei null liegt.

Die Verbindung von Clients zum Squid erfolgt beispielsweise über eine 100-Mbit-Strecke, die Verbindung zwischen Squid und Webserver läuft dagegen nur über eine kostengünstige 2-Mbit-Leitung: Der Webseite selbst ist das nicht anzumerken.

Squid konfigurieren

So viel zur Theorie - nun zur Praxis. Die Installation des Squid unter Linux (und anderen Unix-Derivaten) erfolgt auf dem üblichen Weg: Für einige Distributionen liegen zwar fertige Binaries vor, im Normalfall sollten Sie den Squid aber für Ihr eigenes System übersetzen.

Die komplette Dokumentation, den Quellcode und viele zusätzliche Informationen bietet die Site Squid-Cache.org.

Nach dem Auspacken des Tarballs erzeugen Sie mittels make installdie Squid-Konfigurationsdatei squid.conf. Sie ist deutlich umfangreicher, als man es erwarten würde - zum Glück benötigen Sie aber nur einen kleinen Teil der verfügbaren Konfigurationsoptionen für den Betrieb als Reverse-Proxy. Hier die notwendigen Einstellungen in squid.conf.

http_port: Mit dieser Option stellen Sie ein, auf welchem Port und welcher IP-Adresse der Squid auf eingehende Verbindungen warten soll. Da der Squid als Reverse-Proxy für einen HTTP-Server dienen soll, ist die Portnummer logischerweise 80. Die IP-Adresse ist schlicht und ergreifend die öffentliche IP-Adresse des Systems. Im Wesentlichen brauchen Sie also einen Eintrag wie

http_port aaa.bbb.ccc.ddd:80

Diese grundlegende Einstellung machen Sie relativ weit oben in der Konfigurationsdatei, danach kommt lange nichts mehr, was für den Betrieb als Reverse-Proxy eine Rolle spielt. Die nächste relevante Sektion heißt "Options which affect the Cache-Size".

cache_mem: Mit dieser Option legen Sie den zu verwendenden Hauptspeicher fest. Von Haus aus enthält squid.conf den Eintrag 8 MB - offenbar gibt es bei squid-cache.org nicht sonderlich viel zu cachen. Dieser Wert ist natürlich deutlich zu niedrig. Damit Ihr Cache optimal arbeitet, statten Sie den Rechner am besten mit so viel RAM aus, dass ein möglichst großer Teil des Webauftritts darin Platz hat. Da der Rechner auch noch für andere Dinge ein wenig Speicher braucht, können Sie aber nicht das gesamte RAM an Squid weitergeben. Zwischen 128 und 256 MByte sollten Sie für das System reservieren und den Rest Squid zur Verfügung stellen. Bei der bereits erwähnten Website läuft Squid auf einem Rechner mit 2 GByte und der Einstellung cache_men 1800 MB.

Konfiguration II

maximum_object_size und maximum_object_size_in_memory: Diese beiden Optionen geben an, wie groß ein Objekt maximal sein darf, damit es überhaupt gecached wird, und wie groß ein Objekt maximal sein darf, damit Squid es im Hauptspeicher hält. Diese Werte sind natürlich vom Auftritt abhängig. In manchen Fällen mag es besser sein, wenige große Objekte im RAM zu halten - zum Beispiel, wenn diese sehr häufig angefragt werden. In anderen Fällen ist es besser, viele kleine Objekte im Speicher zu halten. Untersuchen Sie Ihre Website daraufhin, wie groß 90 bis 95 Prozent aller Objekte sind - und verwenden diesen Wert dann als Schwellenwert für die Optionen.

cache_dir: Mit dieser Option geben Sie die Größe und die Lage des Cache-Verzeichnisses an. Ob Objekte überhaupt auf die Festplatte ausgelagert werden sollen, ist jedoch wie zuvor erwähnt vom räumlichen Zusammenhang zwischen Webserver und Squid abhängig. Wenn Sie aus bestimmten Gründen nicht möchten, dass der Squid überhaupt Daten auf die Festplatte auslagert, geben Sie eine Größe von 0 für den Cache an. Ansonsten spricht nichts dagegen, Squid so viel Platz wie nötig auf der Platte einzuräumen.

Warnung vor Logfiles

Die Logfiles des Squid stehen eigentlich in keinem direkten Zusammenhang mit dem Betrieb des Squid als Reverse-Proxy. Betreiben Sie den Squid allerdings auf diese Art, sollten Ihnen eines klar sein: Das "Access Log" des Squid wächst mit der gleichen Geschwindigkeit wie das Ihres Webservers - und es kann bei vielen Besuchern extrem schnell wachsen. Es ist also durchaus sinnvoll, diese Log-Datei gegebenenfalls abzuschalten, oder zumindest ins Logrotate mit aufzunehmen. Die Position der Log-Datei stellen Sie mit der Option cache_access_log ein.

Der Autor hat dabei noch den (wenn auch nicht eindeutig belegbaren) Hinweis anzubringen, dass Squid offenbar nicht allzu gut damit klarkommt, wenn diese Datei eine Größe im GByte-Bereich annimmt. In einem solchen Fall scheint sich Squid gern aus dem Speicher zu verabschieden.

Squid bietet auch eine ganze Reihe von Optionen für die Zugriffskontrolle. Dabei definieren Sie zunächst acl bestimmte Objekte und Daten, die Sie dann mit weiteren Optionen benutzen können. So bewegen Sie Squid beispielsweise mit folgenden Einstellungen dazu, nur noch auf einen bestimmten Satz an http-Requests auf Port 80 zu horchen:

acl Safe_methods method GET HEAD PUT POST CONNECT
acl Safe_ports port 80
http_access deny !Safe_ports
http_access deny !Safe_methods

Darüber hinaus gelten beim Reverse-Proxy natürlich die gleichen Regeln für die Zugriffskontrolle wie beim normalen Squid - und die sind wesentlich umfangreicher, als man sie an dieser Stelle vernünftig behandeln könnte. Für weitere Informationen lesen Sie bitte den tecCHANNEL-Artikel Linux als Proxy-Server oder die Dokumentation zur Zugriffskontrolle.

Die Reverse-Proxy-Optionen

Schließlich finden sich auch noch drei Optionen, die direkt mit dem Betrieb des Squid als Reverse-Proxy zu tun haben.

httpd_accel_port: Diese Option ist nicht zu verwechseln mit "http_port" und legt den Port fest, auf dem der zu cachende Webserver betrieben wird. Normalerweise werden Webserver auf Port 80 betrieben. Wenn Sie aber den Webserver zum Beispiel auf dem gleichen Rechner wie den Squid betreiben, dann muss der Webserver natürlich auf einen anderen als Port 80 horchen. Dieser wird ja bereits durch Squid belegt.

httpd_accel_host: Dieser Parameter bestimmt die IP-Adresse des zu cachenden Webservers.

httpd_accel_single_host on: Soll Squid nur einen einzelnen Webserver cachen, benötigen Sie diese Konfigurationszeile. Für einen Einsatz als Reverse-Proxy für das eigene Webangebot ist das genau die richtige Einstellung.

Das Caching von Webseiten ist im Prinzip eine klasse Angelegenheit - nur will man eben einfach nicht alle Seiten eines Webservers zwischenspeichern. So gibt es sicherlich durch Passwort geschützte Bereiche, die nur bestimmten Benutzern vorbehalten sind und deren Daten man nur ungern im Cache eines externen Rechners wiederfinden möchte. Genauso wenig sollen Verzeichnisse für Testzwecke gecached werden oder dynamisch erzeugte Antworten, die auf Webform Post-Request erfolgen.

Das können Sie auf verschiedenen Wegen erreichen. Der einfachste ist aber die Verwendung der Option hierarchy_stoplist. Diese enthält beliebig viele Strings als Parameter: Taucht in einer Client-Anfrage einer der Strings auf, dann wird die Anfrage direkt an den Webserver weitergegeben und die Antwort nicht zwischengespeichert. Wenn Sie also beispielsweise die Verzeichnisse test und test2 auf dem Webserver haben, deren Inhalte nicht gespeichert werden sollen, dann lautet der benötigte Eintrag:

hierarchy_stoplist test test2

Cache-Attribute im Webserver

Ein auf diese Weise konfigurierter Squid wird dem Webserver schon eine Menge Arbeit abnehmen. Allerdings ist das Thema damit noch nicht komplett behandelt. Wie eingangs erwähnt, liefert Squid nur dann Antworten aus dem Cache, wenn diese noch nicht veraltet sind.

Dabei stellt sich natürlich die Frage, woher Squid denn wissen kann, ob die Haltbarkeitszeit eines Objekts abgelaufen ist. Und das ist relativ einfach zu beantworten: Er kann es natürlich nicht wissen.

Damit Squid also effizient arbeiten kann, muss der Webserver die Objekte mit passenden Haltbarkeitsinformationen ausstatten. Das funktioniert von Webserver zu Webserver unterschiedlich, die Form der Informationen ist aber immer gleich. Ein vom Webserver ausgeliefertes Objekt kann in seinem HTTP-Header vier Tags enthalten, die das Caching steuern: "Last-Modified", "Expires", "Cache-Control" und "Pragma".

Last-Modified legt fest, wann ein Objekt das letzte Mal verändert wurde. Diese Information kann der Squid verwenden, um abzuwägen, ob er ein Objekt erneut vom Server anfordern soll. Besser ist es aber, diese Entscheidung nicht Squid zu überlassen, sondern das Tag Expires zu verwenden. Denn damit kann man selbst festlegen, wann das Objekt abläuft. Erst wenn das der Fall ist, fordert Squid das Objekt neu vom Server an. Bei Bildern, die sich im Normalfall auf dem Server nie verändern, kann man also zum Beispiel eine unendlich lange Haltbarkeit angeben.

Übrigens ist die Vergabe des Expires-Tags selbst dann sinnvoll, wenn Sie keinen Squid betreiben wollen. Immerhin nutzen viele Client-Browser diese Information für die Entscheidung, ob sie ein gegebenes Objekt neu anfordern oder nicht.

Die Tags Cache-Control und Pragma dienen dem gleichen Zweck: Sie informieren Caches darüber, ob eine Seite überhaupt gecached werden soll oder darf. Die beiden Tags sind also hauptsächlich für Seiten wichtig, deren Inhalte nicht zwischengespeichert werden sollen.

Caching für Apache festlegen

Bei Apache legen Sie die Vergabe dieser Tags für Verzeichnisse oder Dateien über httpd.conf fest, wobei Sie außerdem globale Defaults angeben können. Um beispielsweise alle GIF-Dateien, die nicht dediziert mit einem Verfallsdatum ausgezeichnet sind, erst in ferner Zukunft verfallen zu lassen, verwenden Sie die beiden Zeilen:

ExpiresActive On
ExpiresByType image/gif "modification plus 7200 days"

ExpiresByType können Sie natürlich mehrfach verwenden. Um innerhalb eines Containers eine Haltbarkeit zu spezifizieren, verwenden Sie ExpiresDefault. Die Auszeichnung enthält als Parameter einen String, der die Haltbarkeit bestimmt. Um beispielsweise eine Haltbarkeit von etwa zehn Jahren nach der letzten Veränderung des Objekts anzugeben, verwenden Sie:

<Directory "/dir/server/name/public/SehrLangHaltbareFiles">
ExpiresDefault "modification plus 3600 days"</Directory>

Caching bei IIS einstellen und Test

Beim IIS stellen Sie die Haltbarkeit von Objekten direkt über den IIS-Admin mit Hilfe der grafischen Oberfläche ein: IIS kümmert sich dann um die Vergabe der richtigen Tags.

Nach dem ganzen Konfigurationsaufwand am Webserver sollten Sie ermitteln, ob sich die Mühen auch gelohnt haben. Sprich, ob die vorgenommenen Einstellungen den gewünschten Effekt bringen. Zum Glück gibt es dafür ein praktisches Online-Tool: die "Cacheability Engine". Dabei handelt es sich um eine Webseite, die eine URL entgegennimmt, und dann alle zur URL gehörenden Objekte mit allen wichtigen Haltbarkeitsinformationen anzeigt. Auch auf eventuelle Probleme weist die Engine hin.

Ist der Test erfolgreich verlaufen, steht dem Einsatz von Squid als Reverse-Proxy nichts mehr im Weg. (mha)