Один banaction, два транспорта: починка fail2ban VPN jail
ban так же широк, как протокол в его действии. Сравните счётчики цепочки со слушателями, а затем покройте оба транспорта в самом jail.
Ничто в fail2ban само по себе не отбрасывает пакет: оно вызывает действие, и именно это действие называет протокол и порт. Когда jail сообщает о ban, а демон продолжает принимать входы, ban обычно реален и уже, чем следует из лога. Клиент, который переподключается через другой транспорт, никогда не встречает установленное правило. Прежде чем что-то менять, сравните, что установило действие, с тем, что слушает демон, потому что доказательство лежит в цепочке межсетевого экрана, которую записало действие, а не в списке jail.
Читайте цепочку, а не сводку jail
fail2ban вставляет свою цепочку перед цепочкой сервиса, поэтому список счётчиков показывает ровно то, что существует. Цепочка, названная по jail и содержащая одно правило, в столбце протокола которого читается udp, — полное объяснение для продолжающих приходить входов TCP. Отклоняются только пакеты UDP с заблокированного источника. У сервиса есть слушатель TCP, и ничто в этой цепочке его не касается.
Обратите внимание и на эффект соседнего jail. Один хост может выглядеть идеально настроенным лишь потому, что недостающую половину даёт другой jail, а та же сборка ничего не делает там, где этот jail не установлен.
Действие называет один протокол, и именно там оно ломается
Каждый banaction — это шаблон команды межсетевого экрана, и протокол находится в одном из его заполнителей. Узость намеренна, потому что web-jail и DNS-jail не имеют отношения к блокировке одинаковых портов. Это становится ловушкой, когда сервис слушает более одного транспорта, что демоны VPN делают регулярно. Фильтр может отслеживать неудачные входы с обоих транспортов, пока действие покрывает один.
Развёртывания SoftEther и OpenVPN обычно слушают UDP и TCP одновременно, и поскольку строка лога выглядит одинаково в обоих случаях, фильтр следит за обоими. Асимметрия никогда не проявляется в отчёте самого jail. fail2ban правильно посчитал сбои, а затем установил правило, которое действует на половину трафика, на котором пришли эти сбои.
Пусть ban покрывает оба транспорта
Исправьте это в определении jail; правила, написанные вручную, будут перемешаны при следующей перезагрузке. Выпишите два действия, по одному на каждый протокол:
action = %(banaction)s[name=%(__name__)s-tcp, actionname=%(__name__)s-tcp, protocol="tcp", port="%(port)s", chain="%(chain)s"]
%(banaction)s[name=%(__name__)s-udp, actionname=%(__name__)s-udp, protocol="udp", port="%(port)s", chain="%(chain)s"]
Не пытайтесь сократить это с помощью protocol = all. Стандартный banaction — это multiport-действие, и оно разворачивается в -p <protocol> -m multiport --dports <port>; без протокола L4 сопоставлению порта нечего проверять, поэтому iptables отклоняет правило, пока jail по-прежнему сообщает об успешном ban. Действие для всех портов, например iptables-allports или nftables-allports, принимает одну запись, но блокирует все порты у этого источника, что является другим решением и требует собственного обоснования. Оставьте protocol на tcp или udp и примите две записи.
Докажите, что правило существует, вместо того чтобы доверять настройке, потому что настройка описывает намерение, пока цепочка его не удержит:
iptables -S f2b-vpn-tcp
iptables -S f2b-vpn-udp
Каждая цепочка должна перечислять одно правило: в первом -p tcp, во втором -p udp, и оба называют заблокированный адрес. Затем подтвердите, что тот же адрес отклоняется на обоих транспортах. ban, которого вы не видели в цепочке, — это надежда, и следующий отчёт о том же симптоме снова будет стоить того же часа.
Что ban всё ещё упускает, и следующий случай
Действие отклоняет один источник и только на перечисленных в нём портах. Оно ничего не делает против атакующего, который меняет адреса, и не может отделить враждебную машину от выхода операторского NAT, который делят сотни пользователей, где один ban отрезает людей, ничего не сделавших. Убедитесь, что фильтр читает адрес, который у клиента действительно есть, а не переданный заголовок или адрес прокси. Держите окно достаточно коротким, чтобы ошибка истекла сама.
Ничто из этого не говорит в пользу пропуска исправления протокола; это говорит в пользу того, чтобы держать две идеи одновременно. ban уже, чем предполагает сводка jail, и даже полный ban уже угрозы. Поставьте цепочку межсетевого экрана рядом со списком слушателей демона и сравнивайте протокол за протоколом, потому что именно эти два списка решают, может ли ban вообще добраться до сервиса.
Храните команду перезагрузки и список цепочек в runbook рядом с jail. Следующему человеку понадобится и то и другое, а сводка jail не скажет ему ни того, ни другого.