Cette présentation offre un retour d'expérience sur la refonte de service-public.fr. Varnish y a bien-sûr été utilisé comme moteur de cache pour des raisons de performance mais pas seulement. Il a aussi permis l'intégration en marque blanche des contenus d'un CMS grâce aux balises ESI, occasionnant quelques sueurs froides concernant notamment la gestion des cookies. Étant une première expérience sur Varnish, quelques tips vous seront partagés pour bien débuter.
Meetup : http://www.meetup.com/fr-FR/Paris-Varnish-Cache-Meetup/events/231121017/
7. ARCHITECTURE TECHNIQUE
OCTO TECHNOLOGY > THERE IS A BETTER WAY 8
APP ADMIN
JAVA
UTILISATEUR
DILA
RÉDIGEANT
LE CONTENU
INTERNAUTES
ADMINISTRATEURS
TECHNIQUES DILA
COPERIA
ITM
MOTEUR DE
RECHERCHE
AKIOSMPT
VARNISH
APP JAVA
HTTPD
VARNISH
APP JAVA
PAS DE
REDONDANCE DB
DB
REDONDÉE
CMS
EZ
HTTPD
LOGSTAS
H
LE VARNISH JOUE LE RÔLE
DE LOAD BALANCER ET
GARANTIT LE SLA DU CMS
EZPUBLISH
LOADBALANCER
9. EDGE SIDE INCLUDE (ESI)
ESI 1.0 Assemblage de fragments HTML à travers une syntaxe XML
Principaux Intérêts :
> Politique de cache diversifiée dans une page (TTL / Vary)
> Intégration de contenus externe
OCTO TECHNOLOGY > THERE IS A BETTER WAY 10
ESI
+ + =
10. EDGE SIDE INCLUDE (ESI)
OCTO TECHNOLOGY > THERE IS A BETTER WAY 11
<html xmlns:esi="...">
<head>
<title>Hello World!</title>
<meta name="description" value="Hello
World!" />
</head>
<body>
<esi:include src="/hello/world" />
</body>
</html>
<!– Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Mauris sed mauris lacus.
Sed in efficitur orci. Sed id orci
venenatis, cursus orci et, placerat diam.
Sed non tristique ligula. Nunc maximus velit
et felis auctor, sit amet semper purus
ultricies. In imperdiet ac erat a semper.
Interdum et malesuada fames ac ante ipsum
primis in faucibus. Sed sed odio ultrices,
tristique augue ac, sollicitudin metus. --!>
11. EDGE SIDE INCLUDE (ESI)
Approche “Layout First” :
> Servir le squelette principal (non cacheable) à la première requête
> Appeler le contenu central en ESI (cacheable ou non)
> Aller chercher les blocs cacheables de la page en ESI également
OCTO TECHNOLOGY > THERE IS A BETTER WAY 12
<html xmlns:esi="...">
<head>
<meta name="_csrf" value="${_csrf.token}" />
</head>
<body>
<header>Lorem Ipsum</header>
<esi:include src="/esi/content?uri=/request"
/>
<footer>Lorem Ipsum</footer>
</body>
</html>
<!-- here is the main content --!>
layout.html content.html
HEADER
FOOTER
CONTENT
ESI
12. EDGE SIDE INCLUDE (ESI)
Approche “Content First” :
> Servir le contenu principal (cacheable ou non) à la première requête
> Aller chercher les blocs du squelette (cacheable ou non) en ESI
OCTO TECHNOLOGY > THERE IS A BETTER WAY 13
<html xmlns:esi="...">
<head>
<esi:include src="/esi/head" />
</head>
<body>
<esi:include src="/esi/header" />
<!-- here is the main content --!>
<esi:include src="/esi/footer" />
</body>
</html>
<meta name="_csrf"
value="${_csrf.token}"/>
layout.html head.html
CONTENT
HEADER
ESI
FOOTER
ESI
13. VARNISH VS ESIGATE
CACHING REVERSE PROXY
ECRIT EN C
SUPPORT ESI MINIMAL
CUSTOMISATION PAR DSL
VARNISH VCL
OCTO TECHNOLOGY > THERE IS A BETTER WAY 14
IMPLÉMENTATION ESI COMPLÈTE
ECRIT EN JAVA
SUPPORT CACHING REVERSE
PROXY
GESTION DES COOKIES /
ERREURS
CUSTOMISATION PAR
PROPERTIES
14. VARNISH VS ESIGATE
OCTO TECHNOLOGY > THERE IS A BETTER WAY 15
FEATURE (ESI 1.0) ESIGATE VARNISH
<esi:include src="/url" alt="/url-alt" onerror=”continue|display" />
(src only)
<esi:remove>
<a href="http://www.example.com">www.example.com</a>
</esi:remove>
<!--esi
<p>Edge Side Include supported</p>
-->
<esi:comment text="the following animation will have a 24 hr TTL." />
<esi:try>
<esi:attempt>...</esi:attempt>
<esi:except code="404">...</esi:except>
<esi:except code="500">...</esi:except>
<esi:except>...</esi:except>
</esi:try>
<esi:choose>
<esi:when test="..."> ... </esi:when>
<esi:when test="..."> ... </esi:when>
<esi:otherwise> ... </esi:otherwise>
</esi:choose>
<esi:vars>
<img src="http://www.example.com/$(HTTP_COOKIE{type})/hello.gif"/ >
</esi:vars>
<esi:inline name="URI" fetchable="{yes | no}”>
fragment to be stored within an ESI processor
</esi:inline>
15. POURQUOI AVOIR CHOISI VARNISH ?
OCTO TECHNOLOGY > THERE IS A BETTER WAY 16
VARNISH + ESIGATE VOLONTÉ DE
SIMPLIFIER L’ARCHITECTURE
VARNISH DÉJÀ UTILISÉ POUR LE CACHE
EZPUBLISH
VARNISH SOLUTION RECONNUE DANS LE
DOMAINE DU CACHE APPLICATIF
PAS DE PARTIE AUTHENTIFIÉE À L’ÉPOQUE
DU CHOIX
17. RAPPEL : VARNISH 4 FLOW
HOOKS DANS LE CYCLE DE
VIE DE LA REQUÊTE
OCTO TECHNOLOGY > THERE IS A BETTER WAY 18
vcl_recv : requête client reçue
vcl_hash : calcul clé de hash
vcl_hit : objet trouvé en cache
vcl_miss : objet non en cache
vcl_backend_fetch : requête au serveur
vcl_backend_response : réponse du serveur
vcl_deliver : prêt à répondre au client
18. CAS PRATIQUE : SERVICE-PUBLIC.FR
OCTO TECHNOLOGY > THERE IS A BETTER WAY 19
19. CAS PRATIQUE : SERVICE-PUBLIC.FR
OCTO TECHNOLOGY > THERE IS A BETTER WAY 20
<!DOCTYPE html>
<html xmlns:esi="http://www.edge-delivery.org/esi/1.0" lang="fr">
<head>
<title>Vos Questions - Service Public</title>
<meta name="description" content="Le site officiel de
l'administration française - Service Public">
<esi:include src="/esi/head?esiTargetUrl=/vos-questions" />
</head>
<body>
<header class="banner" role="banner">
<esi:include src="/esi/header?esiTargetUrl=/vos-questions" />
</header>
<esi:include src="/esi/search" />
<main class="main" id="main" role="main">
<div class="container main-container">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</main>
<footer class="footer" role="contentinfo">
<esi:include src="/esi/footer" />
</footer>
<esi:include src="/esi/javascripts" />
<esi:include src="/esi/marquage" />
</body>
</html>
20. CAS PRATIQUE : SERVICE-PUBLIC.FR
BANDEAU DE LOGIN SERVI PAR FRAGMENT ESI
CONTENU PRINCIPAL POTENTIELLEMENT EN CACHE
TOKEN CSRF ASSOCIÉ AU FORMULAIRE REGÉNÉRÉ À CHAQUE CHARGEMENT
PAS DE CACHE
TOKEN CSRF LIÉ AU COOKIE DE SESSION
UTILISATEUR ARRIVANT LA PREMIÈRE FOIS SANS COOKIE DE SESSION SE
RETROUVENT AVEC UN TOKEN CSRF INVALIDE
POURQUOI ?
OCTO TECHNOLOGY > THERE IS A BETTER WAY 21
21. PROBLÈME : PERTE DU COOKIE
OCTO TECHNOLOGY > THERE IS A BETTER WAY 22
SQUELETTE
EN CACHE
FRAGMENT
NO CACHE
CLIENT VARNISH BACKEND
UTILISATEUR SANS COOKIE
INITIALEMENT,
L’APPEL AU BACKEND POUR LE
FRAGMENT GÉNÈRE UN
COOKIE
LA RÉPONSE FINALE NE
CONTIENT PLUS DE COOKIE
GET /hello
ESI /header
200 /hello
HIT /hello
22. SOLUTION « REDIRECTION NAVIGATEUR » : PERTE D’UTILISATEURS
OCTO TECHNOLOGY > THERE IS A BETTER WAY 24
SQUELETTE
EN CACHE
FRAGMENT
NO CACHE
CLIENT VARNISH BACKEND
UTILISATEUR SANS COOKIE
INITIALEMENT,
APPEL D’UN ENDPOINT DE
GÉNÉRATION DU COOKIE DE
SESSION,
REDIRECTION DU NAVIGATEUR
VERS LA PAGE INITIALE AVEC
COOKIE DE SESSION
LA DÉSACTIVATION DES
COOKIES ENTRAINE UNE
REDIRECTION INFINIE (ROBOT
INDEXATION, …)
GET /hello
200 /hello
GET /session?redirect=/hello
302 /hello
GET /hello HIT /hello
ESI /header
23. SOLUTION « RESTART INTERNE VARNISH »
OCTO TECHNOLOGY > THERE IS A BETTER WAY 26
SQUELETTE
EN CACHE
FRAGMENT
NO CACHE
CLIENT VARNISH BACKEND
UTILISATEUR SANS COOKIE
INITIALEMENT,
APPEL D’UN ENDPOINT DE
GÉNÉRATION DU COOKIE DE
SESSION,
VARNISH RESTART SUR LA PAGE
INITIALE EN INJECTANT LE
COOKIE DE SESSION
RÉPONSE COHÉRENTE AVEC
UN « SET-COOKIE » DE
SESSION
GET /hello
200 /hello
GET /session?redirect=/hello
RESTART /hello
HIT /hello
ESI /header
Varnish forge les sous-requêtes ESI à partir de la requête
originelle Passage du cookie de session aux sous-
requêtes ESI via la variable req_top (Varnish 4.1+)
26. VCL_RECV
OCTO TECHNOLOGY > THERE IS A BETTER WAY
sub vcl_recv {
if (req.restarts == 0) {
if (req.http.X-Forwarded-For) { # set or append the client.ip to X-Forwarded-For header
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
# Dans un fragment ESI, on récupère le cookie de la requête parente
if (req.esi_level > 0) {
set req.http.Cookie = req_top.http.X-Cookies;
}
call sp_purge;
call sp_ban;
call sp_healthcheck;
if (! std.healthy(apps.backend())) {
return(synth(503, {""}));
}
call sp_choose_backend;
call sp_clean_request;
call sp_session_generate;
# return (hash);
}
27. SP_CLEAN_REQUEST
OCTO TECHNOLOGY > THERE IS A BETTER WAY
sub sp_clean_request {
call sp_clean_request_host;
call sp_clean_request_url;
if (req.http.Cookie) {
# Handle SPPlus webapp cookie. Store it temporarily
set req.http.X-Cookies = ";" + req.http.Cookie;
set req.http.X-Cookies = regsuball(req.http.X-Cookies, "; +", ";");
set req.http.X-Cookies = regsuball(req.http.X-Cookies, ";(SPREMEMBER|SPPLUS_SESSION)=", ";
1=");
set req.http.X-Cookies = regsuball(req.http.X-Cookies, ";[^ ][^;]*", "");
set req.http.X-Cookies = regsuball(req.http.X-Cookies, "^[; ]+|[; ]+$", "");
# Clean empty webapp cookie
if (req.http.X-Cookies ~ "^ *$") {
unset req.http.X-Cookies;
}
# Remove all others cookies
unset req.http.Cookie;
}
}
28. SP_SESSION_GENERATE
OCTO TECHNOLOGY > THERE IS A BETTER WAY
sub sp_session_generate {
if (req.restarts == 0 && req.esi_level == 0 && (req.method == "GET" || req.method == "HEAD")) {
# Préparation de l'URL de redirection
## Encodage URL des '&'
set req.url = regsuball(req.url, "&", "%26");
# Construction de la requête de construction de session
set req.url = "/session" + "?redirect=" + req.url;
# Sélection du backend pour le endpoint de génération de session
call sp_choose_backend;
return (pass);
}
}
29. VCL_DELIVER [SESSION RESPONSE]
OCTO TECHNOLOGY > THERE IS A BETTER WAY
sub vcl_deliver {
if (req.http.X-Cookies) {
set resp.http.Cookie = req.http.X-Cookies;
}
# Intercepte la création de session, uniquement pour la webapp
call sp_session_intercept_redirect;
# Récupère le Set-Cookie originel pour le renvoyer au browser afin qu'il soit conservé
if (req.http.X-Set-Cookie) {
if (! req.http.X-Set-Cookie ~ "^ *$") {
set resp.http.Set-Cookie = req.http.X-Set-Cookie;
}
unset req.http.X-Set-Cookie;
}
# Remove some headers: PHP version
unset resp.http.X-Powered-By;
[...]
}
30. SP_SESSION_INTERCEPT_REDIRECT
OCTO TECHNOLOGY > THERE IS A BETTER WAY
sub sp_session_intercept_redirect {
if (req.url ~ "^/session" && req.http.X-Varnish-Backend ~ "^apps" && resp.status == 302) {
# Récupération de la requête originelle du client
set req.url = resp.http.Location;
if (resp.http.Set-Cookie) {
# Extraction du nouveau cookie de session
set req.http.X-Session-Cookie = regsuball(req.http.X-Session-Cookie, ";(SPPLUS_SESSION)=",
"; 1=");
[...]
# Transfert du header Set-Cookie originel à destination du client final
set req.http.X-Set-Cookie = resp.http.Set-Cookie;
if (! req.http.X-Session-Cookie ~ "^ *$") {
// Supprime le cookie de session existant
set req.http.X-Cookies = regsuball(req.http.X-Cookies, "(^|;s*)(_[_a-
z]+|SPPLUS_SESSION)=[^;]*", "");
// Supprime le préfixe ";" si présent.
set req.http.X-Cookies = regsub(req.http.X-Cookies, "^;s*", "");
}
}
# Concaténation du nouveau cookie de session aux cookies existants
if (req.http.X-Cookies ~ "^ *$") {
set req.http.Cookie = req.http.X-Session-Cookie;
} else {
set req.http.Cookie = req.http.X-Cookies + "; " + req.http.X-Session-Cookie;
}
# Rédémarrage du workflow varnish
return (restart);
}
}
31. VCL_RECV [POST RESTART]
OCTO TECHNOLOGY > THERE IS A BETTER WAY
sub vcl_recv {
if (req.restarts == 0) {
if (req.http.X-Forwarded-For) { # set or append the client.ip to X-Forwarded-For header
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
# Dans un fragment ESI, on récupère le cookie de la requête parente
if (req.esi_level > 0) {
set req.http.Cookie = req_top.http.X-Cookies;
}
call sp_purge;
call sp_ban;
call sp_healthcheck;
if (! std.healthy(apps.backend())) {
return(synth(503, {""}));
}
call sp_choose_backend;
call sp_clean_request;
call sp_session_generate;
# return (hash);
}
32. VCL_BACKEND_*
OCTO TECHNOLOGY > THERE IS A BETTER WAY
sub vcl_backend_fetch {
# Handle SPPlus webapp cookie
if (bereq.http.X-Cookies) {
set bereq.http.Cookie = bereq.http.X-Cookies;
}
}
sub vcl_backend_response {
if (!(beresp.status >= 200 && beresp.status <= 299)) {
# Mark as "Hit-For-Pass" for the next 2 minutes
set beresp.ttl = 120s;
set beresp.uncacheable = true;
return (deliver);
}
set beresp.do_esi = true; // Do ESI processing
set beresp.http.X-Varnish-Backend = beresp.backend.name;
[...]
# Clean SPPlus webapp cookie
if (bereq.http.X-Cookies) {
unset beresp.http.Cookie;
unset beresp.http.X-Cookies;
}
unset beresp.http.X-Set-Cookie;
}
33. VCL_RECV [ESI SUBCALL]
OCTO TECHNOLOGY > THERE IS A BETTER WAY
sub vcl_recv {
if (req.restarts == 0) {
if (req.http.X-Forwarded-For) { # set or append the client.ip to X-Forwarded-For header
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
# Dans un fragment ESI, on récupère le cookie de la requête parente
if (req.esi_level > 0) {
set req.http.Cookie = req_top.http.X-Cookies;
}
call sp_purge;
call sp_ban;
call sp_healthcheck;
if (! std.healthy(apps.backend())) {
return(synth(503, {""}));
}
call sp_choose_backend;
call sp_clean_request;
call sp_session_generate;
# return (hash);
}
34. VCL_DELIVER [FINAL RESPONSE]
OCTO TECHNOLOGY > THERE IS A BETTER WAY
sub vcl_deliver {
if (req.http.X-Cookies) {
set resp.http.Cookie = req.http.X-Cookies;
}
# Intercepte la création de session, uniquement pour la webapp
call sp_session_intercept_redirect;
# Récupère le Set-Cookie originel pour le renvoyer au browser afin qu'il soit conservé
if (req.http.X-Set-Cookie) {
if (! req.http.X-Set-Cookie ~ "^ *$") {
set resp.http.Set-Cookie = req.http.X-Set-Cookie;
}
unset req.http.X-Set-Cookie;
}
# Remove some headers: PHP version
unset resp.http.X-Powered-By;
[...]
}
35. VARNISH 3 : ESICOOKIES…
OCTO TECHNOLOGY > THERE IS A BETTER WAY 40
36. ESI & GESTION D’ERREURS
OCTO TECHNOLOGY > THERE IS A BETTER WAY 41
CLIENT VARNISH BACKEND WEB
GET /hello
200 /hello
GET /hello
BACKEND CMS
SQUELETTE
FRAGMENT
ESI /header
ERROR PAGE
500 /header
BACKEND CMS FONCTIONNEL RETOURNE LE
SQUELETTE
BACKEND WEB KO RETOURNE UNE PAGE
D’ERREUR COMME FRAGMENT ESI
LA PAGE SERVIE A POUR HEADER
UNE PAGE D’ERREUR…
200 /hello
37. ESI & GESTION D’ERREURS : « PALIATIF »
VÉRIFIER LA « BONNE SANTÉ » DU BACKEND SERVANT LES
FRAGMENTS ESI
SERVIR DIRECTEMENT UNE PAGE D’ERREUR EN CAS
D’INDISPONIBILITÉ
OCTO TECHNOLOGY > THERE IS A BETTER WAY 42
sub vcl_recv {
if (req.restarts == 0) {
if (req.http.X-Forwarded-For) { # set or append the client.ip to X-Forwarded-For header
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
[...]
if (! std.healthy(apps.backend())) {
return(synth(503, {""}));
}
[...]
# return (hash);
}
38. POST MORTEM VARNISH + ESI
VARNISH CONFIGURATION LANGUAGE FACILEMENT CUSTOMISABLE (UNE
FOIS S’ÊTRE APPROPRIÉ LE STATE DIAGRAM)
VARNISH OK POUR MASHUP ESI D’UN SITE STATIQUE MARQUE BLANCHE
ATTENTION GESTION COOKIES DANS LES FRAGMENTS ESI
VARNISH OFFRE PEU DE CONTRÔLE SUR MASHUP ESI
COMPLIQUER DE GÉRER ERREURS DANS FRAGMENT UN ESI
VARNISH 4.1 + ESI INTERACTION REQUÊTE PARENTE VIA REQ_TOP
VARNISH NE PERMET PAS DE RÉCUPÉRER NATIVEMENT LES HEADERS
MULTIPLES (CAS DU SET-COOKIE).
VMOD : https://www.varnish-cache.org/vmod/header-manipulation
OCTO TECHNOLOGY > THERE IS A BETTER WAY 43
40. VARNISH 4 FLOW
HOOKS DANS LE CYCLE DE
VIE DE LA REQUÊTE
OCTO TECHNOLOGY > THERE IS A BETTER WAY 45
vcl_recv : requête client reçue
vcl_hash : calcul clé de hash
vcl_hit : objet trouvé en cache
vcl_miss : objet non en cache
vcl_backend_fetch : requête au serveur
vcl_backend_response : réponse du serveur
vcl_deliver : prêt à répondre au client
http://varnish-cache.org/trac/wiki/VCLExampleDefault
41. APPROCHE RETENUE
VARNISH 4 BUILTIN.VCL
OCTO TECHNOLOGY > THERE IS A BETTER WAY 46
DUPLIQUER LE COMPORTEMENT
PAR DÉFAUT VARNISH DANS LE
VCL CUSTOM
CONSERVER LE COMPORTEMENT
PAR DÉFAUT AU MAXIMUM ET
COMPOSER AVEC
Deux approches concernant le comportement
par défaut de la configuration Varnish
Code plus explicite
Modifier aisément le
comportement par défaut
Comportement par défaut
préventif peut être altéré
Profite pas des potentielles
évolutions du builtin.vcl
Comportement par défaut à
connaître, pas explicite
Complexité supplémentaire
(ex : cache cookies)
Protégé par le comportement
builtin du VCL Varnish
Réduit la duplication
42. BUILTIN.VCL - VCL_RECV
OCTO TECHNOLOGY > THERE IS A BETTER WAY
sub vcl_recv {
if (req.method == "PRI") {
/* We do not support SPDY or HTTP/2.0 */
return (synth(405));
}
if (req.method != "GET" &&
req.method != "HEAD" &&
req.method != "PUT" &&
req.method != "POST" &&
req.method != "TRACE" &&
req.method != "OPTIONS" &&
req.method != "DELETE") {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}
if (req.method != "GET" && req.method != "HEAD") {
/* We only deal with GET and HEAD by default */
return (pass);
}
if (req.http.Authorization || req.http.Cookie) {
/* Not cacheable by default */
return (pass);
}
return (hash);
}
https://github.com/varnish/Varnish-
Cache/blob/4.0/bin/varnishd/builtin.vcl
43. CUSTOM.VCL - VCL_RECV
OCTO TECHNOLOGY > THERE IS A BETTER WAY
sub vcl_recv {
[...]
call sp_clean_request_cookie;
# return (hash);
}
DUPLIQUER LE COMPORTEMENT PAR
DÉFAUT VARNISH DANS LE VCL
CUSTOM
CONSERVER LE COMPORTEMENT
PAR DÉFAUT AU MAXIMUM ET
COMPOSER AVEC
sub vcl_recv {
[...]
[...]
return (hash);
}
sub sp_clean_request_cookie {
if (req.http.Cookie) {
# Handle SPPlus webapp cookie. Store it temporarily
set req.http.X-Cookies = ";" + req.http.Cookie;
set req.http.X-Cookies = regsuball(req.http.X-Cookies, "; +", ";");
set req.http.X-Cookies = regsuball(req.http.X-Cookies, ";(SPREMEMBER|SPPLUS_SESSION)=", ";
1=");
set req.http.X-Cookies = regsuball(req.http.X-Cookies, ";[^ ][^;]*", "");
set req.http.X-Cookies = regsuball(req.http.X-Cookies, "^[; ]+|[; ]+$", "");
# Clean empty webapp cookie
if (req.http.X-Cookies ~ "^ *$") {
unset req.http.X-Cookies;
}
# Remove all others cookies
unset req.http.Cookie;
}
}
44. ÉVICTION DE CACHE
OCTO TECHNOLOGY > THERE IS A BETTER WAY 49
PURGE
SUPPRIME IMMÉDIATEMENT UN
OBJET DU CACHE PAR SON URL
UNE URL À LA FOIS
SEULEMENT
CONTENU SUPPRIMÉ DE
MÉMOIRE
BAN
AJOUTE UNE RÈGLE DE
BANNISSEMENT APPLIQUÉE LORS
DE LA REQUÊTE D’UNE PAGE
RÈGLES SOUPLES (REGEX,
HEADERS, …)
RÈGLES VÉRIFIÉES AU
MOMENT DE SERVIR UN
CONTENU
Deux approches concernant l’éviction de cache.
Exposer dès le départ ces mécanismes.
45. PURGE - VCL_RECV
OCTO TECHNOLOGY > THERE IS A BETTER WAY
sub sp_purge {
# Allow purging
if (req.method == "PURGE") {
if (!client.ip ~ invalidators) { # invalidators is the ACL defined at the beginning
# Not from an allowed IP? Then die with an error.
return (synth(405, "This IP is not allowed to send PURGE requests."));
}
# If you got this stage (and didn't error out above), purge the cached result
return (purge);
}
}
NE PAS OUBLIER DE GÉRER CORRECTEMENT UNE
ACCESS CONTROL LIST
46. BAN - VCL_RECV
OCTO TECHNOLOGY > THERE IS A BETTER WAY
sub sp_ban {
# Allow ban
if (req.method == "BAN") {
if (!client.ip ~ invalidators) { # invalidators is the ACL defined at the beginning
# Not from an allowed IP? Then die with an error.
return (synth(405, "Method not allowed"));
}
if (req.http.X-Backend == "CMS") {
ban("obj.http.X-Varnish-Backend ~ ^cms");
} else if (req.http.X-Backend == "WEBAPP") {
if (req.http.X-Flow) {
if (req.http.X-Flow == "ACTU") {
ban("req.url ~ ^/resources-actu/.+ && obj.http.X-Varnish-Backend ~ ^apps");
} else if (req.http.X-Flow == "VDD") {
ban("req.url ~ ^/resources-vdd/.+ && obj.http.X-Varnish-Backend ~ ^apps");
} else if (req.http.X-Flow == "LETTRESP") {
ban("req.url ~ ^/resources-lettresp/.+ && obj.http.X-Varnish-Backend ~ ^apps”);
} else if (req.http.X-Flow == "ITM") {
ban("req.url ~ ^/annuaire/?.* && obj.http.X-Varnish-Backend ~ ^apps");
} else {
return (synth(400, "Bad Request, unexisting X-Flow '" + req.http.X-Flow + "'"));
}
} else {
ban("obj.http.X-Varnish-Backend ~ ^apps");
}
} else {
# HUGE BAN !
ban("req.url ~ ^/?.*$");
}
return (synth(200, "Banned"));
}
}
47. VARNISHTEST
TEST D’INTÉGRATION
LANCEMENT D’UN VÉRITABLE DAEMON VARNISH
POSSIBILITÉ DE « MOCKER » LES BACKENDS
RÉALISER DES ASSERTIONS SUR LA RÉPONSE AU CLIENT
OCTO TECHNOLOGY > THERE IS A BETTER WAY 52
Bien découper votre VCL pour mutualiser au
maximum la configuration pour les tests
vcl 4.0;
# spécifique à l'environnement
include "backends.vcl";
include "acls.vcl";
# politique de cache
include "rules.vcl";
48. VARNISHTEST
OCTO TECHNOLOGY > THERE IS A BETTER WAY
vcl 4.0;
import directors; # load the directors
sub vcl_init {
new apps = directors.round_robin();
new cms = directors.round_robin();
}
ACLS.VCL BACKENDS.TEST.VCL
vcl 4.0;
# ACL for invalidators IP
acl invalidators {
"localhost";
"127.0.0.1";
}
sub vcl_recv {
if (req.restarts == 0) {
if (req.http.X-Forwarded-For) { # set or append the client.ip to X-Forwarded-For header
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
[...]
RULES.VCL
49. VARNISHTEST - TEST.VTC
OCTO TECHNOLOGY > THERE IS A BETTER WAY
varnishtest "Should delete trailing slash"
server server_apps {
rxreq
txresp
accept
rxreq
expect req.url == "/hello/world"
txresp
} -start
varnish v1 -vcl+backend {
include "{{ varnish_location }}/conf/acls.vcl";
include "{{ varnish_location }}/conf/backends.test.vcl";
include "{{ varnish_location }}/conf/rules.vcl";
sub vcl_init {
apps.add_backend(server_apps);
}
} -start
client c1 {
txreq -url "/hello/world/"
rxresp
expect resp.status == 200
} -run
50. VARNISHLOG
USER ET ABUSER DE
VARNISHLOG
OFFRE UNE VUE DÉTAILLÉE DE
TOUTES LES ÉTAPES DU VCL
UTILISER VARNISHLOG QUERY
LANGUAGE POUR S’Y
RETROUVER PLUS FACILEMENT
OCTO TECHNOLOGY > THERE IS A BETTER WAY 55
varnishlog -v –g request
51. MERCI
OCTO TECHNOLOGY > THERE IS A BETTER WAY 56
Benjamin Brabant
@Maastiff
brabant.benjamin@gmail.com
52. OCTO TECHNOLOGY > THERE IS A BETTER WAY 57
VOUS CROYEZ QUE LES TECHNOLOGIES CHANGENT LE MONDE ?
NOUS AUSSI ! REJOIGNEZ-NOUS !
recrutement@octo.com