清漆缓存与后端安全性?

时间:2018-02-08 06:15:06

标签: php caching cookies drupal varnish

我正在尝试使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 front(Drupal)
  • 172.19.0.1 Varnish

所以这是来自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或授权标题,这几行也会强制使用varnish来缓存?
  • 如果两个标头都不可缓存,如何实现某些安全性并限制对后端的访问?
    • 除后端的IP限制外?

提前感谢任何建议。

1 个答案:

答案 0 :(得分:0)

您是对的 - 如果请求包含cookie或授权标头,或者响应设置了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&amp;授权标头。

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

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

如果你有理由以不同的方式思考,你必须修改vcl_recv以不返回&#34;传递&#34;设置Authorzation标头时。您还需要修改Varnish创建缓存响应的哈希方式。请参阅:https://varnish-cache.org/docs/5.2/users-guide/vcl-hashing.html

我不会这样走路。