我曾尝试实施一个系统来阻止恶意 IP。该系统似乎在测试中有效,但在实际环境中,我得到了一些不同的结果。
我尝试做的是,如果连接的错误率 > 10、错误数 > 50 或请求率 > 150,则阻止连接。
首先,我的前端代理具有以下配置:
stick-table type ip size 100k expire 30s store http_err_rate(10000),http_err_cnt,http_req_rate(10000)
tcp-request connection track-sc0 src
tcp-request connection accept if { src -f /etc/haproxy/whitelist.lst }
tcp-request connection reject if { sc0_http_err_rate gt 10 }
tcp-request connection reject if { sc0_http_err_cnt gt 50 }
tcp-request connection reject if { sc0_http_req_rate gt 150 }
我最近对一个 ip 进行了扫描,该 ip 没有被 haproxy 阻止,在被 ip-tables 阻止之前,我检查了该 IP 的统计信息,结果显示:
echo "show table clientsecure key x.x.x.x" | socat stdio /var/run/haproxy.stat
# table: clientsecure, type: ip, size:102400, used:23
xx: key=x.x.x.x use=8 exp=0 http_req_rate(10000)=144 http_err_cnt=34235 http_err_rate(10000)=150
我感觉我对 haproxy 配置有一个根本性的误解。
我是否正确地将 stick-table 与以下 tcp-request 连接规则结合使用?
如果一条规则匹配,“tcp-request connection rejection”是否会阻止传入连接,还是所有规则都需要匹配?
编辑:
经过进一步测试,我发现规则仅在新连接上进行检查。因此,使用“option httpclose”将在达到限制时立即阻止人们。显然出于速度原因,这不是理想的选择,因此将尝试保持活动超时。
答案1
因为我只跟踪前端的连接,所以任何保持活动的连接仍然能够运行请求。所以解决方案是:
前端:
- 仅使用 gpc 创建粘性表
- 追踪联系src 使用 sc1
- 如果 gpc > 0,则创建 acl“is-abuser”
- 如果“is-abuser”则拒绝连接
后端:
- 启动粘性表,其中包含错误率、错误计数、请求率
- 追踪内容src 使用 sc2
- 为错误率、计数、请求率创建滥用 acl
- 创建 acl 以使用 sc1_inc_gpc 增加从前端 stick-table 跟踪的 gpc
- 如果滥用 acls 匹配则拒绝内容并运行然后运行增加 gpc acl
我直接从手册中找到的类似示例(使用 sc0 和 sc1 代替上述解释中的 sc1、sc2):
#Track per-frontend and per-backend counters, block abusers at the frontend when the backend detects abuse(and marks gpc0).
frontend http
# Use General Purpose Couter 0 in SC0 as a global abuse counter
# protecting all our sites
stick-table type ip size 1m expire 5m store gpc0
tcp-request connection track-sc0 src
tcp-request connection reject if { sc0_get_gpc0 gt 0 }
...
use_backend http_dynamic if { path_end .php }
backend http_dynamic
# if a source makes too fast requests to this dynamic site (tracked
# by SC1), block it globally in the frontend.
stick-table type ip size 1m expire 5m store http_req_rate(10s)
acl click_too_fast sc1_http_req_rate gt 10
acl mark_as_abuser sc0_inc_gpc0(http) gt 0
tcp-request content track-sc1 src
tcp-request content reject if click_too_fast mark_as_abuser