Squid als Reverse-Proxy

DebianDer Proxyserver Squid kann nicht nur als Beschleuniger für den Internetzugriff aus dem internen Netzwerk genutzt werden, sondern auch als Beschleuniger für Webserver. Besonders bei dynamischen Webseiten kann so viel Last vom Webserver genommen und die Auslieferung der Webseiten beschleunigt werden.

Die Funktion nennt sich Reverse-Proxy und lässt sich mit nur wenigen Handgriffen konfigurieren. Die Beispielkonfiguration ist für einen Squid in der Version 3.x.

squid.conf

Die gesamte Konfiguration für eine Beispielseite (example.de) könnte wie folgt aussehen.

http_port 80 accel defaultsite=www.example.de vhost
 
cache_peer backend.example.de parent 80 0 no-query originserver name=backend
 
acl sites_backend dstdomain example.de www.example.de
cache_peer_access backend allow sites_backend
 
acl our_sites dstdomain www.example.de
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl Safe_ports port 80          # http
 
http_access allow manager localhost
http_access deny !Safe_ports
http_access allow our_sites
http_access deny all
 
reply_header_access Via deny all
reply_header_access X-Forwarded-for deny all
reply_header_access X-Cache deny all
 
cache_mgr [email protected]
 
forwarded_for on
 
logformat combined \
  %{Host}>h %>a %ui %un [%tl] "%rm %ru  HTTP/%rv" %Hs %<st "%{Referer}>h"\
  "%{User-Agent}>h" %Ss:%Sh
logformat vcombined \
  %{Host}>h %>a %ui %un [%tl] "%rm %ru  HTTP/%rv" %Hs %<st "%{Referer}>h"\
  "%{User-Agent}>h"
 
access_log /var/log/squid3/access.log combined
access_log /var/log/squid3/vaccess.log vcombined

Beschreibung der Konfiguration

Aktivierung der Reverse-Proxy Funktionalität

http_port 80 accel defaultsite=www.example.de vhost

Die Zeile bewirkt, dass alle Anfragen an Port 80 als Reverse-Proxy Anfragen behandelt werden und an einen Backend Server weitergeleitet werden. Zur Interpretation der Anfrage wird der Host Name der Anfrage verwendet. Falls kein Host mit übergeben wird wird www.example.de als Standard definiert.

Definition des Backend Servers

cache_peer backend.example.de parent 80 0 no-query originserver name=backend

Mit dieser Anweisung definiert man den Backend Server. In diesem Beispiel ist der Server an den die Anfragen weitergeleitet werden backend.example.de. Für einen einfacheren Zugriff wird der Name backend für den Server definiert. Es können mehrere Backend Server angegeben werden. Dazu wird einfach die Anweisung für jeden Backend Server angepasst und als neue Zeile in die Konfiguration eingefügt.

Zuweisung der Webseiten

acl sites_backend dstdomain example.de www.example.de
cache_peer_access backend allow sites_backend

Mit den beiden Zeilen werden die Webseiten example.de und www.example.de dem Backend Server backend zugewiesen. Alle Anfragen an die Seiten example.de und www.example.de werden an den backend benannten Server weitergeleitet.

Einstellungen der Access Control List (ACL)

acl our_sites dstdomain backend.example.de
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl Safe_ports port 80          # http
 
http_access allow manager localhost
http_access deny !Safe_ports
http_access allow our_sites
http_access deny all

Hiermit wird definiert wer auf welche Ports und welche Server zugreifen darf. Die ACL unterscheidet sich aufgrund des Einsatzes als Reverse-Proxy deutlich von einer herkömmlichen Squid ACL. Die ACL wird hier anhand des Ziels und nicht wie üblich anhand der Quelle definiert.
Da jeder von überall auf den Proxy zugreifen darf, ist hier das Risiko besonders hoch ausversehen einen offenen Proxy zu konfigurieren. Daher erlaubt man nur den Zugriff auf die wirklich nötigen Ports der Backend Server und verweigert alle restlichen Anfragen.

reply_header_access Via deny all
reply_header_access X-Forwarded-for deny all
reply_header_access X-Cache deny all

Mit den reply_header_access Regeln beseitigt man alle Spuren des Proxy Servers aus den Headern der HTTP Antwort.

Protokollierung

Protokollierung auf dem Webserver

forwarded_for on

Da für den Backend Server alle Anfragen von dem Proxy Server zu kommen scheinen, ist eine ordentliche Auswertung der Logs nicht mehr möglich. Mit der Zeile wird noch ein zusätzlicher Header mit eingefügt, den man dann mit einer Anpassung der Protokollierung auf dem Backend Server mit protokollieren und auswerten kann. Doch auch das ist nicht ganz perfekt.

Protokollierung auf dem Reverse-Proxy

logformat combined \
  %{Host}>h %>a %ui %un [%tl] "%rm %ru  HTTP/%rv" %Hs %<st "%{Referer}>h"\
  "%{User-Agent}>h" %Ss:%Sh
logformat vcombined \
  %{Host}>h %>a %ui %un [%tl] "%rm %ru  HTTP/%rv" %Hs %<st "%{Referer}>h"\
  "%{User-Agent}>h"
 
access_log /var/log/squid3/access.log combined
access_log /var/log/squid3/vaccess.log vcombined

Der Proxyserver beantwortet wenn möglich jede Anfrage aus dem Cache. Um so mehr, desto besser. Somit bekommen aber die Backend Server gar nicht mehr alle Anfragen mit. Die Definition des Logformats und der Log Files ist eine alternative Möglichkeit alle Anfragen bereits auf dem Proxy Server in einem für gängige Software auswertbaren Format zu protokollieren.

2 Gedanken zu „Squid als Reverse-Proxy“

  1. Wie kann ich das machen mit 3 umd mehr domain .


    Hallo Joerg,

    vom Prinzip einfach noch die zusätzlichen Domains ergänzen.
    Falls die Domains auf dem selben Backend liegen, reicht es aus die Domains in den folgenden Zeilen zu ergänzen:

    acl sites_backend dstdomain example.de www.example.de www.beispiel.de beispiel.de

    acl our_sites dstdomain www.example.de www.beispiel.de

    Sollen die Seiten von einem anderen Backend geholt werden, muss der Backend-Server definiert werden.

    cache_peer backend2.example.de parent 80 0 no-query originserver name=backend2

    acl sites_backend2 dstdomain 2example.de www.2example.de
    cache_peer_access backend2 allow sites_backend2

    acl our_sites dstdomain www.2example.de
    acl all src 0.0.0.0/0.0.0.0
    acl manager proto cache_object
    acl localhost src 127.0.0.1/255.255.255.255
    acl Safe_ports port 80 # http

    Ich hoffe das hilft ein wenig weiter…
    Viele Grüße

  2. Moin,moin.

    Klasse Tutorial. Danke!!
    Wie schaffe ich es, das z.B. der User seite.domain.de in den Browser eingibt, der Proxy die Daten von andereseite.domain.de holt und im Browser des Users immernoch seite.domain.de steht, obwohl die Daten von andereseite.domain.de angezeigt werden?
    Ist ja im Prinzip der Sinn eines reverse Proxys die Herkunft der Daten zu verschleiern, oder?
    Irgendwie klappt das bei mir nicht.
    Okay, inzwischen ist ja Squid3 rausgekommen aber daran wird es ja nicht liegen.
    Auf einer VM funktioniert das ohne Probleme (mit Authentifizierung über LDAP) aber auf unserem Linux-Server funktioniert das irgendwie nicht.
    Statt dessen haben wir jetzt eine 1A Weiterleitung. 😐

    squid.conf:
    http_port 80 accel defaultsite=seite.domain.de
    cache_peer andereseite.domain.de parent 80 0 no-query originserver name=myAccel
    acl our_sites dstdomain seite.domain.de

    reply_header_access Via deny all
    reply_header_access X-Forwarded-for deny all
    reply_header_access X-Cache deny all

    acl manager proto cache_object
    acl localhost src 127.0.0.1
    acl Safe_ports port 80

    http_access allow our_sites manager localhost
    cache_peer_access myAccel allow our_sites
    cache_peer_access myAccel deny all

    forwarded_for on
    emulate_httpd_log on
    log_fqdn on
    logformat combined \
    [%tl] %>a %ui %un „%{User-Agent}>h“ %Ss:%Sh
    access_log /var/log/squid3/access.log combined

    Gruß,
    Brainmark


    Moin, moin,

    genaugenommen werden die Daten auch verschleiert. Der Benutzer kommt nie in direkten Kontakt mit dem Backend-Server. Der Webserver kann auch in einem privaten Adressbereich liegen und nur vom Squid erreichbar sein.

    Wenn ich aber die Frage richtig verstehe, suchst Du etwas in Richtung rewriting von URLs.
    Also Benutzer gibt in den Browser adresse1.de ein. Squid soll nun vom Webserver aber die Seite wasanderes.de holen, da der Webserver adresse1.de nicht kennt.

    Das könnte man mit einem eigenen Script z.B. in perl realisieren, das man mit url_rewrite_program in den Squid einbinden kann.


    url_rewrite_program url_rewrite_children 10

    Damit bekommt man zumindest das Umschreiben von URLs hin. Das Problem ist aber nicht ganz so trivial, weil man auch die gesamten Inhalte umschreiben müsste. Werden z.B. Cookies verwendet bekommt man damit ein Problem.

    Viele Grüße
    fk

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.