Dodano zakaz lakierowania, ale zwracany jest stary obiekt

Jan 08 2021

Używam lakieru przed serwerem kafelków, aby buforować kafelki mapbox. Aby usunąć stare kafelki, zamierzałem użyć zakazów, aby skutecznie usunąć dużą liczbę buforowanych kafelków. Mój problem polega na tym, że varnish nadal używa obiektów z pamięci podręcznej (przynajmniej agew odpowiedzi wskazuje na to) i nie kontaktuje się z zapleczem.

Najpierw proszę o http: //varnish/5/3/4.pbf, następnie dodaję blokadę za pomocą curl -X BAN -H 'X-Purge-Regex: 5/3/4.pbf' varnishlub alternatywnie, varnishadma następnie ban obj.http.url ~ 5/3/4.pbfponownie proszę o http: //varnish/5/3/4.pbf.

Na początku moja lista banów jest pusta:

Present bans:
1610117471.434488     1 C

Zakaz został dodany z powodzeniem 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>

i pojawia się na liście banów

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

Po ponownym zażądaniu http: //varnish/5/3/4.pbf lista banów wskazuje, że zakaz został użyty

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

ale wiek odpowiedzi nie wynosi 0, ponieważ jest to nadal obiekt z pierwszego żądania.

Po krótkim czasie zakaz zostaje usunięty:

Present bans:
1610117471.434488     1 C  

Mój vcl_recvwygląda tak, ale błąd jest chyba gdzieś indziej bo też nie działa z 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);
                }
        }
}

Próbowałem też użyć vcl_purgefromhttps://stackoverflow.com/a/61507014 ale to nie pomaga w przypadku zakazów (?).

Używam X-Purge-Regexnagłówka, aby nie martwić się o ucieczkę ze znaków specjalnych, takich jak whttps://stackoverflow.com/a/38526921ale zwykły zakaz obj.http.url ~ 0nie działa.

Używam lakieru 6.5 z vcl 4.0.

Prośba o zablokowanie

*   << 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            

POBIERZ po dodaniu bana

*   << 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  

Powtarzam problem

Aby odtworzyć błąd:

  • git clone https://github.com/Baschdl/varnish-ban-setup.git && cd varnish-ban-setup
  • docker-compose up
  • Otwórz http: // localhost: 8092/5/3 / 1.pbf
  • docker-compose exec varnish varnishadm ban obj.http.url ~ pbf
  • Otwórz ponownie http: // localhost: 8092/5/3 / 1.pbf, a otrzymasz stary obiekt

Odpowiedzi

2 ThijsFeryn Jan 09 2021 at 00:23

obj.http.url ~ 5/3/4.pbfZakaz które wydają, jest dopasowanie do urlnagłówka odpowiedzi.

Pamiętaj: adres URL to nagłówek żądania, a nie nagłówek odpowiedzi. Bez powodu do paniki, to, co robisz, ma sens i jest związane z zakresem tak zwanego czajnika zakazu .

Ban czai się

Zakaz lurker jest wątek, który asynchronicznie przetwarza zakazy na liście obiektów zakaz i dopasowania do zakazów w celu usunięcia wzorców obiektów z pamięci podręcznej.

Blokujący lurker nie działa w zakresie żądania, a jedynie zna zakres obiektu.

Aby pomyślnie dopasować informacje o żądaniu, kontekst żądania można dodać jako nagłówek odpowiedzi. I to właśnie robisz przezobj.http.url

Dlaczego więc zakaz nie działa?

Powodem, dla którego twój ban nie działa, jest to, że nie ustawiłeś go obj.http.urlw pliku VCL. W rezultacie czający się zakaz nie może dopasować do niego żadnych obiektów.

Jak rozwiązać problem

Rozwiązanie jest proste: ustaw brakujące nagłówki w kontekście odpowiedzi zaplecza, jak pokazano poniżej:

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

Kiedy backend odpowie, a tuż przed tym, jak obiekt zostanie zapisany w pamięci podręcznej, możemy ustawić brakujące nagłówki.

Następnie czający się ban będzie mógł dopasować wyrażenie zakazu do odpowiednich obiektów i usunąć je z pamięci podręcznej.

Nie zapominaj, że obiekty nie są natychmiast dopasowywane: są usuwane tylko wtedy, gdy osiągną wartość ban_lurker_age, która jest domyślnie ustawiona na 1 minutę.