如何在Varnish中返回空响应或直接关闭连接?
在Varnish中处理未知主机请求并直接关闭连接
需求背景
当请求到达Varnish服务器时,若请求的Host头对应的服务器名称未知,需要直接关闭连接(类似Nginx返回444的效果)。此前仅在后端Nginx配置了默认服务器返回444,但未配置Varnish时,访问Varnish公网IP会触发Error 503 Backend fetch failed - Backend fetch failed - Guru Meditation错误。
原Nginx配置
server { listen 80 default_server; listen [::]:80 default_server; return 444; } server { listen 80; listen [::]:80; server_name my.example.org; }
问题分析
Nginx返回444时会直接关闭连接,Varnish无法正确解析后端响应,因此返回503错误。对应varnishlog日志片段如下:
- BereqMethod GET - BereqURL / - BereqProtocol HTTP/1.1 ... - BackendOpen 33 default X.X.X.X 80 X.X.X.X 34862 ... - FetchError HTC eof (-1) - BackendClose 33 default ... - BerespStatus 503 - BerespReason Backend fetch failed
解决方案
最优方案是在Varnish的VCL配置中提前拦截未知Host请求,无需转发到后端Nginx,直接关闭连接:
修改后的VCL配置
vcl 4.1; # 定义后端Nginx节点 backend default { .host = "X.X.X.X"; # 替换为你的Nginx后端IP .port = "80"; } sub vcl_recv { # 仅允许指定的Host头,其他请求直接返回444关闭连接 if (req.http.Host != "my.example.org") { return synth(444); } # 保留原有正常请求处理逻辑 } sub vcl_synth { # 针对444状态码设置关闭连接响应头 if (resp.status == 444) { set resp.http.Connection = "close"; return deliver; } }
配置说明
- vcl_recv阶段拦截:请求到达Varnish后立即检查
Host头,不符合指定值时直接返回444,避免向后端发送无效请求,提升性能。 - vcl_synth阶段处理:设置
Connection: close响应头,确保Varnish直接关闭连接,与Nginx返回444的行为完全一致。
内容的提问来源于stack exchange,提问作者luigifab
相关产品推荐
相关产品推荐

