【问题标题】:Varnish cache vs backend security?清漆缓存与后端安全性?
【发布时间】:2018-07-18 15:03:11
【问题描述】:

我正在尝试使 Varnish 在现有的 Silex (PHP Symfony) 后端之间工作,该后端已经在标头和 Drupal 前端产生了带有 max-age 的响应。问题是:

  • Silex 将 Cookie 添加到每个响应中
  • Drupal 将授权字符串添加到每个请求标头中
  • 我发现带有 Cookie 和授权标头的请求通常会丢失缓存。

我首先尝试通过修改 default.vcl 文件来禁用这种“默认”清漆行为,但不幸的是,直到我从请求中删除了 Cookie 和授权字符串,这才起作用。

backend default {
    .host = "172.118.0.1";
    .port = "88";
}

sub vcl_recv {
  if (!(req.url ~ "^/admin/")) {
      unset req.http.Cookie;
  }

  if (req.http.Authorization || req.http.Cookie) {
   /* Not cacheable by default */
   return (pass);
  }
}

我的设置:

  • 172.118.0.1 后端 (Silex)
  • 172.18.0.1 正面(Drupal)
  • 172.19.0.1 清漆

所以这是来自 Drupal 的请求示例,它每次都不会命中缓存并传递到后端,直到我从标头中删除授权行:

*   << Request  >> 17
-   Begin          req 16 rxreq
-   Timestamp      Start: 1518013537.955268 0.000000 0.000000
-   Timestamp      Req: 1518013537.955268 0.000000 0.000000
-   ReqStart       172.19.0.1 49216
-   ReqMethod      GET
-   ReqURL         /silex-api/
-   ReqProtocol    HTTP/1.1
-   ReqHeader      User-Agent: GuzzleHttp/6.2.1 curl/7.38.0 PHP/7.0.26
-   ReqHeader      Host: 172.19.0.1
-   ReqHeader      Content-Type: application/json
-   ReqHeader      Accept: application/hal+json, application/json
-   ReqHeader      x-drupal-run-id: AB1234567890
-   ReqHeader      Authorization: Basic ###############
-   ReqHeader      x-client-ip: 172.18.0.1
-   ReqHeader      X-Forwarded-For: 172.19.0.1
-   VCL_call       RECV
-   VCL_return     pass
-   VCL_call       HASH
-   VCL_return     lookup
-   VCL_call       PASS
-   VCL_return     fetch
-   Link           bereq 18 pass
-   Timestamp      Fetch: 1518013538.496350 0.541082 0.541082
-   RespProtocol   HTTP/1.1
-   RespStatus     200
-   RespReason     OK
-   RespHeader     Date: Wed, 07 Feb 2018 14:25:37 GMT
-   RespHeader     Server: Apache/2.4.10 (Debian)
-   RespHeader     X-Powered-By: PHP/5.6.32
-   RespHeader     Cache-Control: max-age=600, public, s-maxage=600
-   RespHeader     x-content-digest: en93a2e062ff1dfe53e166cd7916ac9e44f3ba3d61100ad01a86228dda44b5b125
-   RespHeader     Content-Length: 1596
-   RespHeader     Age: 1
-   RespHeader     X-Symfony-Cache: GET /silex-api/: fresh
-   RespHeader     Content-Type: application/hal+json
-   RespHeader     X-Varnish: 17
-   RespHeader     Age: 1
-   RespHeader     Via: 1.1 varnish-v4
-   VCL_call       DELIVER
-   VCL_return     deliver
-   Timestamp      Process: 1518013538.496405 0.541137 0.000055
-   RespHeader     Accept-Ranges: bytes
-   Debug          "RES_MODE 2"
-   RespHeader     Connection: keep-alive
-   Timestamp      Resp: 1518013538.496544 0.541276 0.000139
-   ReqAcct        281 0 281 447 1596 2043
-   End

所以我的问题是:

  • 如果我正确理解了 hucking vcl 的概念,并且即使有 Cookie 或 Authorization 标头,这几行假设强制清漆命中缓存?
  • 如果两个标头都不可缓存,如何实现一些安全性并限制对后端的访问?
    • 除了后端的 IP 限制?

提前感谢您的任何建议。

【问题讨论】:

    标签: php caching cookies drupal varnish


    【解决方案1】:

    你是对的——如果请求包含 cookie 或 Authorization 标头,或者响应设置了 cookie,Varnish 不会缓存任何响应。这是在builtin.vcl 中定义的:https://github.com/varnishcache/varnish-cache/blob/master/bin/varnishd/builtin.vcl

    vcl_receive:

    if (req.http.Authorization || req.http.Cookie) {
        /* Not cacheable by default */
        return (pass);
    }
    

    vcl_backend_response:

    } else if (beresp.ttl <= 0s ||
      beresp.http.Set-Cookie ||
      ...) {
        # Mark as "Hit-For-Miss" for the next 2 minutes
        set beresp.ttl = 120s;
        set beresp.uncacheable = true;
    }
    

    因此,如果您希望 Varnish 缓存请求,您需要取消设置 cookie 和授权标头。

    为什么 Varnish 会以这种方式工作 - 因为对请求的响应可能会因 cookie 的不同而不同,并且很可能会因 Authorization 标头而异,因此不可缓存 - 这正是 Varnish 所假设的。

    因此,我认为您永远不想缓存对授权请求的响应。对我来说故事结束。

    如果您确实有理由有不同的想法,则必须修改 vcl_recv 以在设置 Authorzation 标头时不返回“通过”。您还需要修改 Varnish 创建缓存响应的哈希值的方式。见:https://varnish-cache.org/docs/5.2/users-guide/vcl-hashing.html

    我不会走这条路。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-21
      • 1970-01-01
      • 1970-01-01
      • 2013-01-09
      • 2012-04-03
      • 2018-08-13
      • 2018-01-26
      • 2021-05-09
      相关资源
      最近更新 更多