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

fail2ban не может запретить ip на всех портах, если он уже заблокирован для определенного порта

Я использую настраиваемый фильтр в fail2ban для поиска в собственном журнале и запрета ip после 5 банов из любого из обычных фильтров. я использую iptables-allports как действие для этого. Все остальные фильтры настроены с iptables-multiport.

Это конкретная конфигурация в jail.conf

[fail2ban]
enabled  = true
filter   = fail2ban
action   = iptables-allports[name=fail2ban]
logpath  = /var/log/fail2ban.log
maxretry = 5
findtime = 604800
bantime  = 2592000

Мой фильтр fail2ban.conf выглядит так (лишние комментарии удалены)

[Definition]
# Count all bans in the logfile
failregex = fail2ban.actions: WARNING \[(.*)\] Ban <HOST>
# Ignore our own bans, to keep our counts exact.
ignoreregex = fail2ban.actions: WARNING \[fail2ban\] Ban <HOST>

iptables-allports.conf это значение по умолчанию, которое поставляется с fail2ban 0.8.6-3 для Ubuntu 12.04.2

Проблема в том, что всякий раз, когда ip забанен одним из обычных фильтров, скажем sshd, он забанен на 10 минут. Но в пятый раз, когда тот же адрес будет заблокирован, фильтр fail2ban должен заблокировать этот IP-адрес на 30 дней, но, поскольку он уже заблокирован в цепочке fail2ban-ssh, он не работает.

Может быть, проблему легче понять, если вы посмотрите этот журнал

2013-03-19 16:28:34,304 fail2ban.actions: WARNING [ssh] Ban 202.191.128.252
2013-03-19 16:38:34,992 fail2ban.actions: WARNING [ssh] Unban 202.191.128.252
2013-03-19 22:08:58,961 fail2ban.actions: WARNING [ssh] Ban 202.191.128.252
2013-03-19 22:18:59,675 fail2ban.actions: WARNING [ssh] Unban 202.191.128.252
2013-03-20 03:52:25,005 fail2ban.actions: WARNING [ssh] Ban 202.191.128.252
2013-03-20 04:02:25,672 fail2ban.actions: WARNING [ssh] Unban 202.191.128.252
2013-03-20 09:29:51,020 fail2ban.actions: WARNING [ssh] Ban 202.191.128.252
2013-03-20 09:39:51,734 fail2ban.actions: WARNING [ssh] Unban 202.191.128.252
2013-03-20 12:34:01,832 fail2ban.actions: WARNING [ssh] Ban 202.191.128.252
2013-03-20 12:34:03,718 fail2ban.actions: WARNING [fail2ban] 202.191.128.252 already banned
2013-03-20 12:44:02,545 fail2ban.actions: WARNING [ssh] Unban 202.191.128.252

Как видите, fail2ban видит IP-адрес как уже заблокированный, даже если он предназначен для другого порта (или, скорее, для определенного порта, 22 вместо общего «все порты»), и поэтому ничего не делает.

Мне интересно, можно ли и как заставить fail2ban блокировать ip в цепочке fail2ban, даже если он уже забанен по ssh?

Любое руководство приветствуется. Спасибо.

Хотя fail2ban создает iptables цепочка на сервис (например, fail2ban-ssh) проверка существующего бана основана на IP-адресе. Один из способов решения проблемы - сделать fail2ban. разблокировать IP (тикет), если он уже находится в заблокированном списке непосредственно перед тем, как он собирается его заблокировать (снова)

Эти действия происходят в расположенном скрипте python (при установке через apt-get install) в

/usr/share/fail2ban/server

отредактируйте файл actions.py, вы должны увидеть следующий код для __checkban определение

def __checkBan(self):
        ticket = self.jail.getFailTicket()
        if ticket != False:
                aInfo = dict()
                bTicket = BanManager.createBanTicket(ticket)
                aInfo["ip"] = bTicket.getIP()
                aInfo["failures"] = bTicket.getAttempt()
                aInfo["time"] = bTicket.getTime()
                aInfo["matches"] = "".join(bTicket.getMatches())
                if self.__banManager.addBanTicket(bTicket):
                        logSys.warn("[%s] Ban %s" % (self.jail.getName(), aInfo["ip"]))
                        for action in self.__actions:
                                action.execActionBan(aInfo)
                        return True
                else:
                       logSys.warn("[%s] %s already banned" % (self.jail.getName(), aInfo["ip"]))
        return False

изменить / заменить определение на

def __checkBan(self):
        ticket = self.jail.getFailTicket()
        if ticket != False:
                aInfo = dict()
                bTicket = BanManager.createBanTicket(ticket)
                aInfo["ip"] = bTicket.getIP()
                aInfo["failures"] = bTicket.getAttempt()
                aInfo["time"] = bTicket.getTime()
                aInfo["matches"] = "".join(bTicket.getMatches())
                # changes from here ...
                if not self.__banManager.addBanTicket(bTicket):
                        logSys.warn("[%s] first unban %s before ban" % (self.jail.getName(), aInfo["ip"]))
                        self.__unBan(ticket)
                        self.__banManager.addBanTicket(bTicket)
                logSys.warn("[%s] Ban %s" % (self.jail.getName(), aInfo["ip"]))
                for action in self.__actions:
                        action.execActionBan(aInfo)
                return True
                # else:
                #       logSys.warn("[%s] %s already banned" % (self.jail.getName(), 
                #                                                                                       aInfo["ip"]))
        #return False

и перезапустите fail2ban (например, /etc/init.d/fail2ban restart) пока наверное не надо ...

Примечание: если вы хотите «поиграть» с этим, вы можете указать правила брандмауэра (iptables).

iptables -L

и удалите правило, созданное fail2ban, чтобы получить доступ и принудительно выполнить «повторный бан»

iptables -D fail2ban-ssh xxxx

где xxxx - номер правила в этой цепочке из списка iptables -L fail2ban-ssh

если ваш хост за NAT, то блокировка ip в INPUT не сработает. вместо этого вам нужно выбрать ВПЕРЕД.

например, я использую Asterisk в Docker, поэтому блокировка INPUT не сработает. Я сделал роль тюрьмы вот так:

[asterisk]
enabled = true
filter = asterisk
action = iptables-allports[chain=FORWARD, name=asterisk, protocol=all, blocktype=DROP]
logpath = /home/asterisk/logs/messages
bantime = 10800
maxretry = 2

Я вижу, что количество падающих пакетов увеличивается, как показано на рисунке.

введите описание изображения здесь