HAProxy基于CF-Connecting-IP限制/wp-login.php POST请求速率失效问题求助
HAProxy基于CF-Connecting-IP限制/wp-login.php POST请求速率失效问题求助
你好呀,看了你的HAProxy配置,问题其实出在统计维度不匹配和逻辑对应错误上,我帮你拆解下:
首先看你原配置的核心矛盾:
你在stick table里声明的是存储http_req_rate(20s)——这是HAProxy自动帮你统计20秒内请求速率的内置指标,不需要手动去递增;但后面你又用sc-inc-gpc0(0)去操作通用计数器,可你根本没在stick table里声明要存储gpc0这个维度,等于这个计数器压根没在内存里初始化,自然永远是0,sc_get_gpc0(0) gt 3的条件永远不成立,所以不会触发拒绝。
另外,原配置里的track-sc0位置虽然没问题,但逻辑上要确保先追踪IP,再做计数或速率检查,这个顺序可以再明确下。
给你两个修正后的可行方案,选一个适合你的:
方案一:用HAProxy内置的自动速率统计(更简洁高效)
这种方式不需要手动计数,HAProxy会自动帮你统计每个IP的请求速率:
# 创建stick table,自动统计20秒内的请求速率,存储IP维度,过期时间20秒 stick-table type ip size 1m expire 20s store http_req_rate(20s) # 优先通过CF-Connecting-IP追踪会话(必须在速率检查前执行) http-request track-sc0 hdr(CF-Connecting-IP) # 定义匹配规则:目标路径和POST方法 acl monitored_url path_beg -i /wp-login.php acl is_post method POST # 当满足条件且速率超过3次/20秒时,直接拒绝请求 http-request deny if monitored_url is_post { sc0_http_req_rate gt 3 }
方案二:用手动通用计数器(适合需要自定义计数逻辑的场景)
如果以后你需要更灵活的计数规则(比如只统计失败请求),可以用这种手动计数的方式:
# 创建stick table,存储通用计数器gpc0,过期时间20秒 stick-table type ip size 1m expire 20s store gpc0(0) # 先追踪CF-Connecting-IP http-request track-sc0 hdr(CF-Connecting-IP) # 定义匹配规则 acl monitored_url path_beg -i /wp-login.php acl is_post method POST # 满足条件时,手动递增计数器 http-request sc-inc-gpc0(0) if monitored_url is_post # 当计数器超过3时,拒绝请求(注意要加上匹配条件,避免误杀其他请求) http-request deny if monitored_url is_post { sc_get_gpc0(0) gt 3 }
最后给你提个验证小技巧:可以在HAProxy的日志格式里加上%[hdr(CF-Connecting-IP)],确认Cloudflare的真实IP头确实传送到HAProxy了,比如日志格式改成:
log-format "%h %[hdr(CF-Connecting-IP)] %r %s %b"
如果日志里看不到正确的客户端IP,那得先确保Cloudflare的请求头没有被中间节点篡改。
备注:内容来源于stack exchange,提问作者Frankie
相关产品推荐
相关产品推荐

