Hitch, der TLS Doktor

Ein Einblick tief in den Maschinenraum unserer Webserver – Obacht es wird technisch:

Bis heute wurden fast alle Webseiten der Bergischen Universität über das nicht verschlüsselte Protokoll HTTP ausgeliefert. Nur bei Seiten, welche sensible Daten erheben und von denen wir darüber hinaus Kenntnis hatten, wurden verschlüsselt per HTTPS an die Anwender gebracht. Das ist nun anders – alle Webseiten, welche durch das zentrale CMS TYPO3 ausgeliefert werden und auf eine Domain mit der Endung .uni-wuppertal.de hören, werden standardmäßig verschlüsselt. Siehe hierzu unsere Meldung von Heute.

Damit das funktioniert, haben wir eine neue Software im Einsatz, welche die notwendigen Zertifikate verwaltet und gleichzeitig unseren Webbeschleuniger varnish beliefert: Hitch!

Nicht der Date-Doktor, sondern eher der TLS Doktor. Hitch ist ein sogenannter terminierender SSL-Proxy. Das bedeutet, er nimmt SSL-Verbindungen entgegen, entschlüsselt diese, reicht das ganze weiter an unseren Webproxy varnish, wartet auf Antwort, verschlüsselt diese wieder und liefert die Webseite an den Kunden aus. Hitch ist ein sogenannter „dummer“ Proxy, kann also im Gegensatz zu HAProxy keinerlei Manipulationen vornehmen oder gar regelbasiert Unterscheidungen treffen, sondern nur „auspacken-weiterleiten-einpacken-ausliefern“ betreiben 😉

Nachfolgend unsere Config dazu, da ist nahezu Standard und nix besonderes:

frontend = {
  host = "*"
  port = "443"
}
backend = "[127.0.0.1]:6086"    # 6086 is the default Varnish PROXY port.
workers = 2                    # number of CPU cores

daemon = on
user = "nobody"
group = "nogroup"
syslog-facility = "daemon"

# Enable to let clients negotiate HTTP/2 with ALPN. (default off)
#alpn-protos = "http/2, http/1.1"

# run Varnish as backend over PROXY; varnishd -a :80 -a localhost:6086,PROXY ..
write-proxy-v2 = on             # Write PROXY header

# List of PEM files, each with key, certificates and dhparams
pem-file = "/path/to/pemfile.pem"

# Which ciphers do we support:
ciphers = "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"

Hitch lauscht auf 443, leitet intern alles an varnish auf Port 6086 weiter. Dazu verwendet er das PROXY V2 Protokoll. Damit nun alle Seiten der Universität aus TYPO3 verschlüsselt werden, weisen wir varnish an, alle auf Port 80 einkommenden Verbindungen für die Domains, welche auf uni-wuppertal.de enden, auf HTTPS, also Port 443, weiterzuleiten:

import std;

sub vcl_recv {
    if (std.port(local.ip) == 80 && req.http.host ~ "(?i)uni-wuppertal.de$" ) {
        if (req.http.host !~ "^(www.)?(ausnahmen|kommen|hierhin).uni-wuppertal.de$" ) {
            set req.http.x-redir = "https://" + req.http.host + req.url;
            return(synth(301));
        }
    }
}

Hier gibt es allerdings im zweiten if-Statement einen Ausnahmeblock, da wir für einige Domains im Namensraum uni-wuppertal.de derzeit keine Umleitung vornehmen. Diese lassen sich aber an zwei Händen abzählen.
Die eigentliche Umleitung wird dann in sub vcl_synth vorgenommen:

sub vcl_synth {
    if (resp.status == 301) {
        set resp.http.Location = req.http.x-redir;
        return (deliver);
    }
}

Wer also einen leistungsfähigen SSL Proxy benötigt, dem sei der leichtgewichtige Hitch durchaus an’s Herz gelegt. Das er aus dem selben Hause wie varnish kommt, ist für uns natürlich noch ein weiterer Vorteil.


Fiese Bots, Crawler und sonstiges Getier

Darstellung der varnish ArchitekturDann und wann werden unsere Webserver von fiesem Getier genervt. Spam-Bots, durchgeknallte Crawler und Vulnerability Scanner fallen von Zeit zu Zeit über die Webseiten her und produzieren eine Menge unnötiger Requests und damit Last auf dem Maschinen. Sucht man danach im Web, so findet man eine Menge Anleitungen, wie man den auch bei uns genutzten Webserver Apache so konfiguriert, dass er diese Anfragen ausfiltert und abweist.

Das kann man so machen, ist aber meiner Meinung nach nicht der beste Weg, da noch immer die „böse Anfrage“ direkt an den Webserver gerichtet ist und dieser sich trotzdem damit auseinandersetzen muss. Das wiederum bedeutet immer noch Last auf den Maschinen. Viel besser ist es, diese Art Anfragen gar nicht erst zum Webserver durchzulassen, sondern vorher abzufangen. Da wir den Webbeschleuniger varnish verwenden, ist das relativ einfach.

Jede Anfrage wird von varnish beantwortet. Dieser entscheidet, ob er eine zwischengespeicherte (gecachte) Version der Webseite hat, die er dem Anfragendem zurückgeben kann, oder ob er TYPO3 fragen muss, um eine aktuelle Version zu erhalten. Das ganze macht er mit einer atemberaubenden Geschwindigkeit, so dass wir ihm auch getrost noch weitere Aufgaben übertragen können. Nämlich die „bösen Anfragen“ direkt zu verwerfen und gar nicht erst weiterzuleiten.

Das ganze geht nun mit folgendem Codeschnipsel:

if (
    req.http.user-agent == "^$"
    # UA enthält…
    || req.http.user-agent ~ "^boeserFinger"
    # UA ist exakt gleich…
    || req.http.user-agent ~ "WebVulnCrawl.blogspot.com/1.0 libwww-perl/5.803"
    ) {
      # Frei konfigurierbare Fehlermeldung, beispielsweise entsprechend
      # RFC 2324 (Hyper Text Coffee Pot Control Protocol, HTCPCP)
      return (synth(418,"I'm a teapot"));
    }

Erklärung:

Varnish prüft nun bei jedem eingehenden Request im HTTP Header ob dort ein bestimmter User-Agent (also eine Kennung, die der Anfragende mitsendet) vorhanden ist. Auf dieser Basis lässt er die Anfrage entweder zu oder verwirft diese. Näher beschriebene Zeilen des Codes wie folgt:

  • Zeile 2: Anfragen, die gar keinen User-Agent enthalten
  • Zeile 4: Anfragen, deren User-Agent mit boeserFinger beginnen
  • Zeile 6: Anfragen mit einem ganz bestimmten User-Agent

All diese Anfragen werden direkt durch varnish mit dem HTTP Status 418 beantwortet und damit verworfen. Das Ganze wird in die vcl_recv gepackt und schon sind wir die bösen Jungs los. Das ganze kann man natürlich relativ einfach erweitern und sich so vor fiesen Bots, Crawlern und sonstigem Getier ganz gut schützen.

Und ja, ich weiß, dass man den User-Agent sehr einfach manipulieren kann. Aber 95% der Skriptkiddies lassen sowas out of the Box laufen. Und um die anderen 5% müssen wir uns dann persönlich kümmern.