Назад | Перейти на главную страницу

Haproxy Block if http_req_rate (60s)> 20 в 3 раза?

Это образец конфигурации,

frontend fe_app

    bind 0.0.0.0:8484 name http
    acl has_auth_header req.fhdr(api-key) -m found



    acl mark_as_abuser       sc0_inc_gpc0(be_429_table_api) gt 10
    acl req_rate_api_abuse   sc0_http_req_rate(be_429_table_api) gt 10


    http-request set-header X-Concat %[req.fhdr(api-key)]_%[src] if has_auth_header
    http-request track-sc0 req.fhdr(X-Concat) table be_429_table_api if has_auth_header
    capture request header X-Concat len 100 

    use_backend be_429_slow_down if mark_as_abuser req_rate_api_abuse has_auth_header

    default_backend be_default

backend be_429_table_api
    stick-table type string size 100k expire 10s store http_req_rate(10s),http_req_cnt,gpc0,gpt0

backend be_429_slow_down
    timeout tarpit 10s
    http-request tarpit

И я тестировал с watch -n2 'echo "show table be_429_table_api" | socat stdio unix:/var/run/haproxy.sock'

Проблема возникает при получении запроса gpc0 автоматически начинает увеличиваться. Пока не истечет срок действия таблицы. Кажется, это не связано с http_req_rate в любом случае. Тогда для чего нужен этот счетчик?

Мне нужен счетчик, который увеличивается только при http_req_rate> 10. Поэтому, когда оно превышает 3 (т.е. нарушитель повторяет его более 3 раз в течение 1 м), я могу заблокировать. Что-то вроде следующего

1) 14:00:00: http_req_rate> 10, abuae_counter = 1

2) 14:00:07: http_req_rate> 10, abuse_counter = 2

3) 14:00:17: http_req_rate> 10 abuse_counter = 3

4) 14:00:45: http_req_rate> 10 abuse_counter = 4> Заблокировать

Тогда я могу просто использовать

use_backend be_429_slow_down if abuse_counter has_auth_header

Как этого добиться? Я думал об использовании lua или set.var, но ничего не помогло.

если вам нужен простой счет с большим отрезком времени, вы можете использовать

frontend website
    bind :80
    stick-table  type ip  size 100k  expire store http_req_rate(24h)
    http-request track-sc0 src
    http-request deny deny_status 429 if { sc_http_req_rate(0) gt 20 }
    default_backend servers

Я удалил параметр expires из таблицы стикеров, как указано в документации:

A stick table record expires and is removed after a period of inactivity by the client, as set by the expire parameter. That’s just a way of freeing up space. Without an expire parameter, oldest records are evicted when the storage becomes full