我们在 HAProxy 服务器后面运行了一个 Web 服务缓存反向代理配置。后端服务器Cache-Control
正确地发送所有响应的标头,因此 HAProxy 可以根据 HTTP 规范缓存所有响应。
但是,当最终用户在 Google Chrome 等浏览器中点击 Shift+Reload 按钮时,客户端 (Chrome) 会发送Pragma: no-cache
并Cache-Control: no-cache
强制 HAProxy 始终从后端服务器获取请求。显然,DDoS 攻击可以使用同样的技巧,轻松对后端服务器造成更多负载。
我们知道缓存头是正确的,Pragma: no-cache
当请求可以直接从 HAProxy 缓存中满足时,我们如何配置 HAProxy 来忽略客户端提交的请求并避免调用后端?
我知道对于通用代理使用来说忽略这个标头是不行的,但在这种情况下,我们控制反向代理和后端,所以我们知道这是没问题的。
cache-control: no-cache
以下是来自后端服务器的响应示例,当客户端发送时,后端将重新执行该响应pragma: no-cache
:
cache-control: public, max-age=31536000, s-maxage=31536000
content-length: 463
content-type: image/svg+xml
date: Thu, 24 Jun 2021 14:14:19 GMT
etag: "338"
expires: Fri, 24 Jun 2022 14:14:19 GMT
server: Apache
x-content-type-options: nosniff
显然完全再次从后端服务器获取此信息毫无意义,因为对于使用给定 URL 的任何用户,此信息有效期为一年。另外值得注意的是NGINX 默认不遵守 [client] Pragma 标头。
答案1
Web 浏览器发送的 Cache-Control 和 Pragma 标头会干扰 HAProxy,如果 cache-control 或 pragma 标头为“no-cache”,则由于无法缓存,导致缓存几乎无法使用。要绕过此问题,您只需确保先删除 Cache-Control 标头,然后再使用 http-request del-header 删除 Pragma 标头,然后再尝试使用或存储缓存中的任何内容:
http-request del-header Cache-Control
http-request del-header Pragma
http-request cache-use mycache
http-response cache-store mycache