Docker(Lando)环境Varnish处理BAN/PURGE请求报405错误排查
问题原因
返回405 Not allowed from 172.29.0.3和容器网络连通性无关,核心是VCL配置存在两个疏漏:
- 仅定义了
purge访问控制列表,但没有在vcl_recv流程中编写BAN请求方法的匹配处理逻辑。Varnish默认会拦截所有未明确声明处理逻辑的自定义请求方法,直接返回405,根本不会走到ACL校验环节。 - ACL中写入
"appserver"主机名的规则存在失效风险:Varnish加载VCL时会一次性将域名解析为IP,若appserver容器重启后IP变更、或VCL加载时appserver尚未完成DNS注册,该条规则会直接失效。
修正方案
调整VCL配置,补全BAN请求的处理分支,参考配置如下:
# 访问控制列表保留必要规则即可,开发环境无需配置全量放行规则 acl purge { "localhost"; "127.0.0.1"; "::1"; "172.0.0.0/8"; # 覆盖Docker默认网桥网段,包含报错中出现的172.29.0.3地址 } sub vcl_recv { # 新增BAN请求处理逻辑 if (req.method == "BAN") { # 校验来源IP是否在允许列表内 if (!client.ip ~ purge) { return (synth(405, "Not allowed from " + client.ip)); } # 执行缓存封禁逻辑,可根据自身业务调整匹配规则 if (req.http.X-Ban-Host) { ban("req.http.host == " + req.http.X-Ban-Host + " && req.url ~ " + req.url); } else { ban("req.url ~ " + req.url); } # 处理完成直接返回结果,不进入后续后端转发/缓存查询流程 return (synth(200, "BAN request processed")); } # 此处保留原有业务相关的VCL规则,如缓存规则、后端转发规则等 # ... }
验证与注意事项
- 配置修改后执行
varnishreload命令重载VCL,或直接重启Varnish容器让规则生效。 - 从appserver发起BAN请求时,若为多站点部署,建议携带
X-Ban-Host请求头指定待清除缓存的站点域名,避免误删其他站点的缓存。 - 不建议在ACL中配置
0.0.0.0/0这类全放行规则,哪怕是本地开发环境也尽量仅放行Docker内网网段,避免后续上线生产环境时漏改配置造成安全风险。 - 若重载规则后仍报错,可在Varnish容器内执行
varnishlog -g request -q 'ReqMethod eq "BAN"'命令抓包,确认Varnish实际收到的客户端IP是否属于已放行的网段。
内容的提问来源于stack exchange,提问作者Miloš Kroulík
相关产品推荐
相关产品推荐

