Я пытался установить ограничение скорости для некоторых запросов HTTP POST на моем веб-сайте. Он отлично работает, за исключением одной детали: срок действия моей записи в моей таблице стикеров всегда сбрасывается до 30 секунд, что означает, что если клиент по ошибке отправит запрос через 29 секунд после блокировки, он снова будет заблокирован для 30 секунд.
Вот моя конфигурация, урезанная до минимума для удобства чтения:
frontend http-in
mode http
bind *:80
### Request limiting
# Declare stick table
stick-table type string size 100k expire 30s store gpc0
# Inspect layer 7
tcp-request inspect-delay 15s
# Declare ACLs
acl source_is_abuser sc0_get_gpc0 gt 0
tcp-request content track-sc0 req.cook(frontend) if !source_is_abuser
### End Request limiting
use_backend rate-limit if source_is_abuser
default_backend mybackend
backend mybackend
mode http
stick-table type string size 100k expire 30s store http_req_rate(30s)
tcp-request content track-sc1 req.cook(frontend) if METH_POST
acl post_req_rate_abuse sc1_http_req_rate gt 30
acl mark_as_abuser sc0_inc_gpc0 gt 0
tcp-request content accept if post_req_rate_abuse mark_as_abuser
server myLocalhost 127.0.0.1:8081
backend rate-limit
mode http
errorfile 503 /usr/local/etc/haproxy/rate-limit.http
В этой конфигурации, как только клиент делает более 1 запроса в секунду в течение 30 секунд, этот клиент помечается как нарушитель mybackend
. Затем следующий запрос, как и ожидалось, блокируется http-in
внешний интерфейс.
Однако каждый раз, когда текущая отметка source_is_abuser
клиент отправляет запрос, счетчик истечения срока http-in
Стик-таблица сбрасывается на 30 секунд. Я ожидаю, что счетчик истечения срока действия продолжит снижаться, поскольку соединение предположительно отслеживается только тогда, когда !source_is_abuser
.
Любое понимание того, что я делаю неправильно?
Чтобы проверить счетчик без обновления его значения, вы можете использовать table_http_req_rate. В вашем случае вы можете поместить приведенную ниже конфигурацию в свой интерфейс, чтобы вы могли отклонить запрос до достижения таблицы стикеров.
http-request deny if { key,table_http_req_rate(name_of_your_table) gt 30 }
Дополнительная ссылка: Stick table doc