Nützliches zu Varnish Cache

Hier kommen nützliche Dinge zum Varnish Cache hinein, da ich mich aktuell damit beschäftige.

Allgemein

Varnish ist ein Caching-Proxy, der vor den Webserver vorgeschaltet wird und dessen Inhalte zwischenspeichert, um sie schneller ausliefern zu können, ohne jedes Mal den Webserver selbst bemühen zu müssen.

Dabei legt Varnish die gecachten Daten entweder auf der Platte ab oder im Arbeitsspeicher des Servers.

Projektseite: Varnish

Debian

Auf Debian Wheezy gibt es aktuell die Version 3 von Varnish.

  • req.method ist dort noch nicht verfügbar.

Terminologie

Angenommen der Webserver ist Apache, dann ist dieser das Backend. Der Browser des Benutzers ist der Client.

Alle weiteren Begrifflichkeiten zum Verständnis von Varnish gibt es hier.

Dokumentation

Caching nur ohne Cookies

Per Design cacht Varnish nur Anfragen, die keine Cookies bzw. Antworten, die keine Anfragen zum Setzen solcher enthalten.

Beides lässt sich jedoch in Varnish herausfiltern, dann funktionieren jedoch ein paar Dinge in auf einer Webseite nicht mehr. Lässt man dagegen zu, dass Cookies verwendet werden, kann nicht allzu viel gecacht werden.

Durch das Entfernen der Cookies verliert man also jede Individualisierung der Seite.

Details zu Varnish und Cookies gibt es unter https://www.varnish-cache.org/docs/3.0/tutorial/cookies.html.

Weiterführende Informationen zu Cookies: https://en.wikipedia.org/wiki/HTTP_cookie.

Cookies überprüfen

Bei Verwendung von Firefox drückt man [F12], um die Developer Tools zu öffnen, klickt auf den Reiter “Network”. Dann lädt man die entsprechende Seite, klickt einen der Get-Einträge in der Liste an und klickt rechts in der Leiste auf den Reiter “Cookies”:

VirtualHosts

Varnish mit verschiedenen Anwendungen

Logdateien?

Varnish legt keine Logdateien an sondern hält diese im Speicher vor – bis zu einer maximalen Größe, die man z. B. unter Debian in der Datei /etc/default/varnish über die Variable MEMLOCK festlegt.

Wenn man wirklich logs benötigt, kann man das mitgelieferte Programm varnishncsa nutzen, um dessen Ausgabe in eine Datei umzuleiten. Die Ausgabe ist kompatibel mit dem Format combined von Apache.

Z. B. die Ausgabe von:

varnishncsa -c -F '%h %{Varnish:hitmiss}x %l %u %t "%r" %s %b "%{Referer}i" "%{User-agent}i"'

Ergibt:

1.2.x.x hit - - [18/Mar/2014:01:57:48 +0100] "GET https://domain.tld/ HTTP/1.1" 200 20943 "-" "Mozilla/5.0 (Windows NT 6.1; rv:6.0) Gecko/20110814 Firefox/6.0 Google favicon"
...

Purge und Ban

Purge

Um bestimmte Inhalte zu Purgen, kann man nun z. B. folgendes auf dem Server machen:

curl -X PURGE https://domain.tld/url/foo

Man erhält die Antwort:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>200 Purged.</title>
</head>
<body>
<h1>Error 200 Purged.</h1>
<p>Purged.</p>
<h3>Guru Meditation:</h3>
<p>XID: 2113469310</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>

Dazu muss der Server natürlich auf den Header PURGE hören, siehe hier.

Eigene Funktionen

Man kann in Varnish eigene Funktionen definieren; diese haben jedoch keine Parameter.

Man definiert eine Funktion z. B. mit:

sub name_of_function {
   #inhalt
}

Dann kann man an jeder Stelle diese Funktion aufrufen mit:

call name_of_function;

Dabei funktioniert der “call” so, als ob der entsprechende Code in die aufrufende Stelle eingefügt würde.

Innerhalb einer Funktion stehen alle Objekte zur Verfügung, die auch in der aufrufenden Funktion verfügbar sind (?).

Verwendet man z. B. return(xyz) innhalb der eigenen Funktion, so wird NICHT zur aufrufende Funktion zurückgesprungen.

Bei Bestimmten referern einen Fehler ausgeben oder umleiten

Alle folgenden Zeilen kommen in die Funktion vcl_fetch():

Zur vorherigen Seite zurückschicken

  if (req.http.referer && req.http.referer ~ "dooofe-domain.tld") {
        set beresp.http.location = req.http.referer;
        set beresp.status = 302;
        return(deliver);
    }

Zu bestimmter Seite umleiten

  if (req.http.referer && req.http.referer ~ "dooofe-domain.tld") {
    set beresp.http.location = "https://neue-domain.tld";
    set beresp.status = 302;
        return(deliver);
    }

Nur einen Fehler ausgeben

  if (req.http.referer && req.http.referer ~ "dooofe-domain.tld") {
    error 403 "Trollololollll";
    }
Zuletzt geändert: 2023-01-10 20:08:32 +0100 CET: init