L'interdiction de vernis est ajoutée mais l'ancien objet est retourné

Jan 08 2021

J'utilise du vernis devant un serveur de tuiles pour mettre en cache les tuiles mapbox. Pour supprimer les anciennes tuiles, j'avais l'intention d'utiliser des interdictions pour supprimer efficacement un grand nombre de tuiles mises en cache. Mon problème est que le vernis utilise toujours les objets mis en cache (au moins le agedans la réponse l'indique) et ne contacte pas le backend.

Je demande d'abord http: //varnish/5/3/4.pbf, puis j'ajoute une interdiction avec curl -X BAN -H 'X-Purge-Regex: 5/3/4.pbf' varnishou alternativement varnishadmet ensuite ban obj.http.url ~ 5/3/4.pbfet ensuite je demande à nouveau http: //varnish/5/3/4.pbf.

Au début, ma liste d'interdiction est vide:

Present bans:
1610117471.434488     1 C

L'interdiction est ajoutée avec succès avec curl -X BAN -H 'X-Purge-Regex: 5/3/4.pbf' varnish

<!DOCTYPE html>
<html>
  <head>
    <title>200 Ban added</title>
  </head>
  <body>
    <h1>Error 200 Ban added</h1>
    <p>Ban added</p>
    <h3>Guru Meditation:</h3>
    <p>XID: 8</p>
    <hr>
    <p>Varnish cache server</p>
  </body>
</html>

et apparaît dans la liste des bannissements

Present bans:
1610117369.028870     0 -  obj.http.url ~ 5/3/4.pbf
1610117307.220739     1 C  

Après avoir demandé à nouveau http: //varnish/5/3/4.pbf, la liste d'interdiction indique que l'interdiction a été utilisée

Present bans:
1610117471.434488     1 -  obj.http.url ~ 5/3/4.pbf

mais l'âge de la réponse n'est pas 0, car il s'agit toujours de l'objet de la première requête.

Après un court laps de temps, l'interdiction est supprimée:

Present bans:
1610117471.434488     1 C  

Mon vcl_recvressemble à ceci mais l'erreur est probablement ailleurs car elle ne fonctionne pas non plus avec varnishadm:

sub vcl_recv {
    unset req.http.cookie;

    # Allowing PURGE from localhost
    if (req.method == "BAN"||req.method == "PURGE") {
                if (!client.ip ~ purge) {
                        return(synth(405,"Not allowed."));
                }
                if (req.method == "BAN") {
                    ban("obj.http.url ~ " + req.http.X-Purge-Regex);

                    # Throw a synthetic page so the
                    # request won't go to the backend.
                    return(synth(200, "Ban added"));
                }
                if (req.method == "PURGE") {
                    return (purge);
                }
        }
}

J'ai aussi essayé d'utiliser le vcl_purgefromhttps://stackoverflow.com/a/61507014 mais cela ne semble pas aider pour les interdictions (?).

J'utilise l'en- X-Purge-Regextête pour ne pas m'inquiéter d'avoir à échapper des caractères spéciaux comme danshttps://stackoverflow.com/a/38526921mais juste une interdiction comme obj.http.url ~ 0ne fonctionne pas.

J'utilise le vernis 6.5 avec vcl 4.0.

Demande d'interdiction

*   << Request  >> 54        
-   Begin          req 53 rxreq
-   Timestamp      Start: 1610121483.345437 0.000000 0.000000
-   Timestamp      Req: 1610121483.345437 0.000000 0.000000
-   VCL_use        boot
-   ReqStart       192.168.48.2 50882 http
-   ReqMethod      BAN
-   ReqURL         /
-   ReqProtocol    HTTP/1.1
-   ReqHeader      Host: varnish-volatile
-   ReqHeader      User-Agent: curl/7.64.0
-   ReqHeader      Accept: */*
-   ReqHeader      X-Purge-Regex: 0
-   ReqHeader      X-Forwarded-For: 192.168.48.2
-   VCL_call       RECV
-   VCL_acl        MATCH purge "importer"
-   VCL_return     synth
-   VCL_call       HASH
-   VCL_return     lookup
-   RespProtocol   HTTP/1.1
-   RespStatus     200
-   RespReason     Ban added
-   RespHeader     Date: Fri, 08 Jan 2021 15:58:03 GMT
-   RespHeader     Server: Varnish
-   RespHeader     X-Varnish: 54
-   VCL_call       SYNTH
-   RespHeader     Content-Type: text/html; charset=utf-8
-   RespHeader     Retry-After: 5
-   VCL_return     deliver
-   Timestamp      Process: 1610121483.347281 0.001844 0.001844
-   RespHeader     Content-Length: 246
-   Storage        malloc Transient
-   Filters        
-   RespHeader     Accept-Ranges: bytes
-   RespHeader     Connection: keep-alive
-   Timestamp      Resp: 1610121483.347557 0.002120 0.000276
-   ReqAcct        98 0 98 218 246 464
-   End            

OBTENIR après avoir ajouté l'interdiction

*   << Request  >> 32806     
-   Begin          req 32805 rxreq
-   Timestamp      Start: 1610121552.733872 0.000000 0.000000
-   Timestamp      Req: 1610121552.733872 0.000000 0.000000
-   VCL_use        boot
-   ReqStart       192.168.48.1 55176 http
-   ReqMethod      GET
-   ReqURL         /public.snow_db/0/0/0.pbf
-   ReqProtocol    HTTP/1.1
-   ReqHeader      Host: localhost:8090
-   ReqHeader      User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:84.0) Gecko/20100101 Firefox/84.0
-   ReqHeader      Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
-   ReqHeader      Accept-Language: en-US,en;q=0.5
-   ReqHeader      Accept-Encoding: gzip, deflate
-   ReqHeader      DNT: 1
-   ReqHeader      Connection: keep-alive
-   ReqHeader      Upgrade-Insecure-Requests: 1
-   ReqHeader      Pragma: no-cache
-   ReqHeader      Cache-Control: no-cache
-   ReqHeader      X-Forwarded-For: 192.168.48.1
-   VCL_call       RECV
-   ReqUnset       Host: localhost:8090
-   ReqHeader      host: localhost:8090
-   VCL_return     hash
-   ReqUnset       Accept-Encoding: gzip, deflate
-   ReqHeader      Accept-Encoding: gzip
-   VCL_call       HASH
-   VCL_return     lookup
-   Hit            28 601789.331504 10.000000 0.000000
-   VCL_call       HIT
-   VCL_return     deliver
-   RespProtocol   HTTP/1.1
-   RespStatus     200
-   RespReason     OK
-   RespHeader     content-encoding: gzip
-   RespHeader     content-type: application/x-protobuf
-   RespHeader     date: Fri, 08 Jan 2021 15:09:02 GMT
-   RespHeader     Vary: Accept-Encoding
-   RespHeader     X-Varnish: 32806 28
-   RespHeader     Age: 3010
-   RespHeader     Via: 1.1 varnish (Varnish/6.5)
-   VCL_call       DELIVER
-   VCL_return     deliver
-   Timestamp      Process: 1610121552.734070 0.000197 0.000197
-   Filters        
-   RespHeader     Accept-Ranges: bytes
-   RespHeader     Content-Length: 295
-   RespHeader     Connection: keep-alive
-   Timestamp      Resp: 1610121552.734217 0.000345 0.000147
-   ReqAcct        414 0 414 272 295 567
-   End  

Reproduire le problème

Pour reproduire le bogue:

  • git clone https://github.com/Baschdl/varnish-ban-setup.git && cd varnish-ban-setup
  • docker-compose up
  • Ouvrez http: // localhost: 8092/5/3 / 1.pbf
  • docker-compose exec varnish varnishadm ban obj.http.url ~ pbf
  • Ouvrez à nouveau http: // localhost: 8092/5/3 / 1.pbf et vous obtiendrez l'ancien objet

Réponses

2 ThijsFeryn Jan 09 2021 at 00:23

L' obj.http.url ~ 5/3/4.pbfinterdiction que vous émettez correspond à un en- urltête de réponse.

N'oubliez pas: l'URL est un en-tête de demande, pas un en-tête de réponse. Aucune raison de paniquer, ce que vous faites est parfaitement logique et est lié à la portée de la soi-disant interdiction qui se cache .

Ban lurker

L' interdiction lurker est un thread qui traite de manière asynchrone les interdictions de la liste d'interdiction et associe les objets aux interdictions afin de supprimer les modèles d'objets du cache.

L'interdiction lurker n'opère pas dans une portée de requête, mais est seulement conscient de la portée de l'objet.

Afin de faire correspondre avec succès les informations de la demande, le contexte de la demande peut être ajouté en tant qu'en-tête de réponse. Et c'est ce que tu fais viaobj.http.url

Alors pourquoi l'interdiction ne fonctionne-t-elle pas?

La raison pour laquelle votre interdiction ne fonctionne pas est que vous n'avez pas défini obj.http.urldans votre fichier VCL. En conséquence, l'interdiction qui rôde ne peut associer aucun objet à celle-ci.

Comment résoudre le problème

La solution est simple: définissez les en-têtes manquants dans le contexte de réponse du backend, comme illustré ci-dessous:

sub vcl_backend_response {
    set beresp.http.url = bereq.url;
    set beresp.http.host = bereq.http.host;
}

Lorsque le backend répond, et juste avant que l'objet ne soit stocké dans le cache, nous pouvons définir les en-têtes manquants.

Après cela, le lurker d'interdiction pourra faire correspondre l'expression d'interdiction aux bons objets et les supprimer du cache.

N'oubliez pas que les objets ne sont pas immédiatement mis en correspondance: ils ne sont supprimés que lorsqu'ils atteignent le ban_lurker_age, qui est défini sur 1 minute par défaut.