haproxy BADREQ 错误

haproxy BADREQ 错误

我在 haproxy 日志中看到类似以下的错误:

Jul 18 17:05:30 localhost haproxy[8247]: 188.223.50.7:51940 [18/Jul/2011:17:05:24.339] http_proxy_ads http_proxy_ads/<NOSRV> -1/-1/-1/-1/6001 408 212 - - cR-- 100/89/0/0/0 0/0 "<BADREQ>" 
Jul 18 17:05:30 localhost haproxy[8247]: 188.223.50.7:51943 [18/Jul/2011:17:05:24.341] http_proxy_ads http_proxy_ads/<NOSRV> -1/-1/-1/-1/6000 408 212 - - cR-- 99/88/0/0/0 0/0 "<BADREQ>" 

ETC...

到目前为止,我已尝试增加客户端超时(从 3 秒增加到 6 秒),并将 http 请求缓冲区从 16k 增加到 32k。错误仍然出现。

有人可以指导我在这里寻找什么吗?

答案1

如果浏览器没有使用所有连接,浏览器的预连接也可能导致BADREQ这种情况。例如,当用户在每个浏览器中只下载一个文件时。

这意味着有两个可能的原因(BADREQ已使用 HAProxy v1.5-dev24 验证):cR--CR--

  1. 未使用的连接:这意味着对于 HTTP(S),客户端通过 TCP 连接,但直到timeout http-request( CR--) 或客户端再次关闭连接 ( cR--) 才发送 HTTP 请求标头。原因:来自普通客户端或负载均衡器的预连接或来自扫描的未使用连接。
  2. 错误请求。客户端发送了错误请求。这些错误应该在每个统计套接字中可见(请参阅 womble 之前的回答)。

大多数现代浏览器(例如 Firefox 或 Chrome)都在预连接我发现 Firefox 或 Chrome 总是打开至少 2 个连接,即使浏览器只执行一个请求,例如下载文件(例如仅下载http://cdn.sstatic.net/serverfault/img/favicon.ico

增加 HAProxy 配置中的值timeout http-request有助于减少此类未使用连接的日志条目,因为值越高意味着客户端使用该连接的可能性越大,但您也面临服务器无法再处理所有打开(空闲)连接的风险。如果您在 HAProxy 前面使用其他负载均衡器(如 Amazon ELB),请检查 HAProxy 中的超时是否与负载均衡器匹配,因为它们也可能使用预连接。

对于未使用的连接,您可以option dontlognull在 HAProxy 中禁用此日志条目。引用自HAProxy 文档对于此选项:

通常建议不要在不受控制的环境(例如:互联网)中使用此选项,否则不会记录扫描和其他恶意活动。

答案2

=> The client never completed its request, which was aborted by the
   time-out ("c---") after 5s, while the proxy was waiting for the request
   headers ("-R--").  Nothing was sent to any server, but the proxy could
   send a 408 return code to the client.

解决方案:将“超时 http 请求”更改为 20 秒或更长,而不是 5 秒。

答案3

在这个问题上浪费了一天时间。我们发现一些请求标头太大。HAProxy 的默认最大大小为 8k(所有标头合计),而我们公司喜欢使用 Cookie。在我们的案例中,大约 8% 的请求标头太大,因此截断第 8092 个字节之后。

来自文档:

如果 HTTP 请求大于 (tune.bufsize - tune.maxrewrite),haproxy 将返回 HTTP 400 (Bad Request) 错误。同样,如果 HTTP 响应大于此大小,haproxy 将返回 HTTP 502 (Bad Gateway)。

我们haproxy.cfg使用以下值更新了文件:

global
  # request limit is (bufsize - maxrewrite), our desired limit is 16k (8k is default)
  tune.maxrewrite  16384
  tune.bufsize     32768

希望能帮助到你!

答案4

BADREQ 只是表示客户端发送了一个错误请求;在 HTTP 模式下,这可能意味着客户端出错了,你对此无能为力。要查看确切的错误是什么,请连接到统计套接字(使用 socat)并运行show errors。很有可能有人试图在其他 Web 服务器上运行漏洞,因此你可以忽略它。

相关内容