Я использую fail2ban / firewalld
для ограничения доступа ботов к серверу Nginx
. Обычно конфигурация соответствующей тюрьмы выглядит так:
[nginx-botsearch]
#banaction = iptables-multiport
enabled = true
filter = nginx-botsearch
logpath = /var/log/nginx*/*access*.log
maxretry = 3
bantime = 3600
Это работает, как ожидалось (по умолчанию для запрета используется firewallcmd-ipset
), то есть команда iptables -L
показывает запись в цепочке INPUT_direct
:
REJECT tcp -- anywhere anywhere multiport dports http,https match-set fail2ban-nginx-botsearch src reject-with icmp-port-unreachable
с соответствующим ipset
из fail2ban-nginx-botsearch
.
Однако я заметил странное поведение, когда время запрета
увеличено. Все работает как положено для bantime <= 4294967
. Когда я устанавливаю bantime = 4294968
и перезагружаю службу fail2ban
, запись в выводе iptables
отсутствует (ipset не создается) и действительно, при тестировании с, например, утилита ab
показывает, что запрет не применяется принудительно. Интересно, что использование banaction = iptables-multiport
работает даже для «больших» запретов. В чем может быть причина такого поведения? Я использую fail2ban v 0.9.7 на CentOS 7.
Это не совсем проблема, связанная с fail2ban
, скорее, ошибка в коде netfilter
в вашем ядре. Короче говоря, ваша версия ipset
имеет целочисленное переполнение для параметра timeout
, поэтому вы видите непредсказуемое поведение, когда оно превышает 32-битное целое число.
Вы не видите этого с мультипортом поскольку он не использует этот код и вместо этого полагается на свои собственные устройства для отслеживания таймаутов.
Вот ссылка на исправление этой проблемы в коде netfilter.