lighttpd vor apache

Schon seit längerem hab’ ich über eine Möglichkeit nachgedacht, eventuelle Lastspitzen auf VirtualHosts abzufangen ohne dabei andere VirtualHosts zu beeinträchtigen. Nun, die Lösung ist gefunden. Vorgehensweise:

  • lighty lauscht an allen externen Interfaces an Port 80
  • apache lauscht an localhost:80 und *:443
  • lighty macht einen Proxy auf localhost:80, per Default

Dabei taucht, ganz offensichtlich, ein Problem auf: Apache behandelt nur Verbindungen von localhost und loggt die auch als solche. Alle Statistiktools und sonstige Auswertungen bzw Authentifizierungen wären kaputt. Die Lösung ist einfach und elegant: mod_rpaf auf dem apache installiert und aktivert, schon werden Variablen wie REMOTE_ADDR etc, auf die ursprünglichen Werte gesetzt. Alles ganz so als ob Apache den Request direkt behandelt hätte, nur der zusätzliche Header X-Forwarded-For kündet von der Aktion.

Jetzt haben wir also einen kleinen, schlanken, schnellen Server, der alle Verbindungen einfach nur an das Monster weiterreicht. Nun trete also der Fall ein, dass eine Kundendomain plötzlich extrem hohe Zugriffszahlen hat:

Ohne lighty wird Apache für jeden Request einen Prozess erstellen, mitsamt mod_php und allem was dazugehört. Der Server – und damit alle Kundendomains darauf – wären schwer oder gar nicht erreichbar. Nicht gut, weil man auch schlecht filtern und umleiten kann.

Mit lighty besteht das Problem erstmal unverändert weiter, denn es wird alles durchgereicht. Man hat aber die Möglichkeit, Ausnahmen zu definieren:

$HTTP["host"] == "irgendein.kun.de" {
  proxy.server = () # proxy abschalten
  # konfiguration fuer die Domain, evtl simple statische Seite
}

Damit wären alle anderen Hosts weiterin funktional “as normal” und die Last wird vom lighty weggefangen. Wie der lighty die wegfängt ist ganz phänomenal:

apachebench, 100 Verbindungen parallel, 50000 Requests

13645 www 4028K  2960K RUN      0:29 30.18% 30.18% lighttpd

die längste Zeit verbrät’ der Prozessor im System mit Interrupts etc., apachebench selber schluckt auch 30% CPU.

Das tolle aber ist nicht allein die Geschwindigkeit, mit der die Anfragen beantwortet werden (ca 1800 pro Sekunde), sondern insbesondere der Speicherverbrauch – mit geradeeinmal 3Mb für alles – regelrecht lachhaft. Zum Vergleich: ein Apache-Prozess ist auf der Kiste — dank mod_php et al — etwa 35Mb schwer, um 100 Verbindungen zu bearbeiten wären dann 3.5Gb Speicher belegt (weswegen mein Apache auch nicht soviele Prozesse haben darf um sich nicht selber in die Swap-Wüste zu katapultieren).

Ich bin schlichtweg begeistert von der Lösung, muss jetzt aber nochmal nachdenken, ob ich mir durch den Proxy nicht irgendeine Sicherheitslücke einfahre – insbesondere mal in die Sourcen von mod_rpaf schauen, nicht daß sich das irgendwie eine andere REMOTE_ADDR unterjubeln lässt.

Update: mod_rpaf lässt sich durch bereits gesetzte X-Forwarded-For nicht aus der Ruhe bringen und nimmt korrekterweise den zuletzt hinzugefügten, der nur durch den Proxy gesetzt sein kann. Es macht dies auch nur bei Verbindungen von 127.0.0.1 – ein fälschen der REMOTE_ADDR wäre also “nur” von localhost aus möglich. Hmm, ein möglicher Angriffsvektor. Ob man den in Kauf nehmen will/kann/darf/muss?

Ein Kommentar zu “lighttpd vor apache”

  1. René

    Hey sehr schöner Artikel,

    klingt sehr interessant und ist eigentlich genau das was ich gesucht hab. Kannst du mir die genaue Lighty Konfiguration:

    * lighty lauscht an allen externen Interfaces an Port 80
    * apache lauscht an localhost:80 und *:443
    * lighty macht einen Proxy auf localhost:80, per Default
    

    per Mail schicken? Ich würd das heute Abend gern mal ausprobieren.

    Vielen Dank, Grüße René

Einen Kommentar schreiben:

Bitte schreib' in das folgende Feld die Zahl 123: