Krisevarnish

Denne informasjonen er utdatert anno september 2016; se Varnish for nåværende oppsett.

Varnish er en cachende revers-proxy som har ord på seg for å være svært rask. Fordelen med en slik reversproxy er primært å kunne cache dynamisk genererte (men statiske) websider for å kunne levere dem ut med vesentlig mindre CPU-ressurser enn å kalle Perl/Python/PHP/whatever for å generere dem, men det gir også en fin liten ekstra bonus selv ved cache-misses, i at man slipper å holde et Apache-barn (og evt. Postgres-barn) oppe mens man leverer siden til brukeren (og under keepalive).

Vi har ingen Varnish i vanlig drift på Samfundet, men til trafikkriser (f.eks. store billettslipp) kan det være greit å sette opp som et hack for å ta unna litt last. Configen under er fra Robyn-slippet på UKA-11, til referanse.

VCL-config

backend cirkus {
    .host = "129.241.93.17";
    .port = "80";
}

sub vcl_recv {
    /* Denne er standard, for å få klient-IPen (det virker dog ikke så bra med stud; se under) */
    if (req.http.x-forwarded-for) {
        set req.http.X-Forwarded-For =
            req.http.X-Forwarded-For ", " client.ip;
    } else {
        set req.http.X-Forwarded-For = client.ip;
    }

    /* Spesialconfig for uka.no-hoster */
    if (req.http.host ~ "uka.no$") {
        /*
         * Send alltid til www.uka.no. Dette er så man f.eks. kan sette opp cached.uka.no
         * og teste mot den, uten faktisk å måtte endre på DNS for www.uka.no.
         */
        set req.http.host = "www.uka.no";
        set req.backend = cirkus;

        /*
         * Om vi kommer fra localhost eller en lokal IP, antar vi at det er stud,
         * og setter et eget header for å signalisere til backenden at tilkoblingen
         * foregår over SSL. (Det finnes ikke noe standardheader.)
         */
        if (client.ip = "127.0.0.1" || client.ip = "129.241.93.35" || client.ip == "129.241.93.53") {
            set req.http.x-uka-ssl = "yes";
        }

        /* Alt som ikke er GET eller HEAD er umulig å cache. */
        if (req.request != "GET" && req.request != "HEAD") {
            return (pass);
        }

        /*
         * /login og slikt kan heller ikke caches. Merk at /nyheter er spesielt
         * per UKA-11; det brukes til Innsida. Dette brekker.
         */
        if (req.url ~ "^/(login|admin|innsida)" || req.http.Authorization) {
            return (pass);
        }

        /* Fjern Google Analytics-cookien, for å gjøre ting cachebart. */
        remove req.http.Cookie;
        return (lookup);
     }
}

/*
 * Erstatt standardhashen med en som tar hensyn til om x-uka-ssl er satt
 * eller ikke, slik at SSL- og ikke-SSL-sider caches forskjellig (uka.no
 * oppfører seg forskjellig for de to). Resten av funksjonen er standard.
 */
sub vcl_hash {
    set req.hash += req.url;
    if (req.http.host) {
        set req.hash += req.http.host;
    } else {
        set req.hash += server.ip;
    }
    if (req.http.x-uka-ssl) {
        set req.hash += req.http.x-uka-ssl;
    }
    return (hash);
}

sub vcl_fetch {
    if (req.http.host ~ "uka.no$") {
        if (!(req.url ~ "^/(login|admin|innsida)") && !req.http.Authorization) {
            /* For "vanlige" (ikke-autentiserte) sider, ikke send ved noen session-cookie. */ 
            unset beresp.http.set-cookie;

            /* Overstyr cachingen med vår egen policy. */
            unset beresp.http.expires;
            if (req.url ~ "^/media/") {
                set beresp.ttl = 4w;
            } else {
                set beresp.ttl = 15m;
            }
            return (deliver);
        }
    }
}

stud

Varnish snakker ikke SSL selv; for det trenger du enda en liten proxy på utsiden. Vi har brukt stud, som er veldig bare-bones å sette opp, men visstnok skalerer bra. Ulempen er at det ser ut for Varnish som at alle tilkoblinger kommer fra samme IP; stud og Varnish kan i skrivende stund ikke kommunisere den ekte IPen til hverandre på noen fornuftig måte.

Først og fremst må du sørge for å forberede sertifikatet ditt. cat sammen (i denne rekkfefølgen) sertifikatet, evt. sertifikatkjede, og privatnøkkelen til én fil (husk at den ikke skal være world-readable), og start opp stud med f.eks.

stud --ssl -n 16 -b 129.241.93.53,80 -f 129.241.93.53,443 uka-with-chain.pem 

Se også dokumentasjonen for hvordan du evt. får sesjonscachen til å fungere, for ekstra ytelse.

--ssl er tydeligvis noe vi trengte for å unngå issues med Chrome, -n 16 er 16 kjerner (reduser til færre om du har), -b er backenden og -f er frontend-IPen (kan være f.eks. *,443).

Vi har også prøvd stunnel, men den hadde rare timeoutissues når Varnish timet ut persistente tilkoblinger. Dessuten er nginx en mulighet om du er glad i å lese russisk dokumentasjon, men det ryktes at den ikke yter så godt for SSL.

Lenker: Start, gammel dokumentasjon

Epost: itk@samfundet.no | Telefon: 992 15 925 | Sist endret: 2016-09-01 18:09 | Revisjon: 5 (historie, blame) | Totalt: 1880 kB | Rediger