Я использую настраиваемый фильтр в 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
Я вижу, что количество падающих пакетов увеличивается, как показано на рисунке.