Я попытался реализовать систему блокировки 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, выполняющий сканирование, которое не было заблокировано haproxy, перед блокировкой ip-таблицами я проверил статистику на 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-запроса?
Блокирует ли "tcp-request connection reject" входящие соединения, если соответствует одно правило, или все они должны совпадать?
Редактировать:
При дальнейшем тестировании я выяснил, что правила проверяются только для новых подключений. Таким образом, использование "option httpclose" остановит людей, как только они достигнут предела. Очевидно, не идеально по соображениям скорости, так что поэкспериментируем с тайм-аутами сохранения активности.
Поскольку я отслеживал только соединение на внешнем интерфейсе, любые поддерживаемые соединения по-прежнему могли выполнять запросы. Итак, решение:
Внешний интерфейс:
Бэкенды:
Подобный пример я нашел прямо из руководства (используя 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