в debian

Настройка связки Apache + Fail2ban в Debian


Fail2ban — сервис, отслеживающий log–файлы запущенных программ, и на основании указанных условий блокирующий нарушителей по IP-адресу. Давайте разберемся с защитой от атак на популярный web-сервер Apache!

Считаем, что в вашей системе уже установлен и нормально функционирует Apache. Установка fail2ban не должна вызывать трудностей:

apt-get update && apt-get install fail2ban

Настройки защиты конкретных сервисов по умолчанию находятся в конфигурационном файле /etc/fail2ban/jail.conf. Чтобы не потерять внесенные изменения при обновлениях, копируем эти настройки в новый файл, с которым и будем работать:

cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Далее необходимо отредактировать параметры по умолчанию (общие для всех цепочек), которые находятся в секции [DEFAULT]:

[DEFAULT]
destemail = admin@example.com #email, на который присылать уведомления
ignoreip  = 127.0.0.0/8 192.168.0.0/16 92.29.98.235 #IP–адреса, которые не должны быть заблокированы
mta             = sendmail
action    = %(action_mwl)s #выполнить действие banaction и отправить email-уведомление, включающее "whois"-информацию и строки из log-файла, которые привели к бану
banaction       = iptables-multiport #заблокировать IP-адрес в iptables при помощи модуля multiports 
findtime  = 60 #интервал в секундах, за которое событие должно повториться определённое количество раз
bantime   = 3600 #время бана в секундах
maxretry  = 60 #количество подозрительных совпадений, после которых применяется правило

После изменения параметров по умолчанию, можно приступать непосредственно к настройке jail’ов — секций, которые мы намерены защищать. В данном примере это будут [apache], [apache-noscript], [apache-overflows] и [apache-badbots], которые выглядят так:

[apache]
# блокировка ошибки basic authentication 
enabled = true
port  = http,https
filter = apache-auth
logpath = /var/log/apache*/*error.log #следует изменить, если log-файл находится в другом месте
maxretry = 3 #переопределяем значение, определенное в секции [DEFAULT]
findtime = 600 #переопределяем значение, определенное в секции [DEFAULT]
[apache-noscript]
# следует использовать, если у вас статический сайт
enabled = true
port  = http,https
filter = apache-noscript
logpath = /var/log/apache*/*error.log #следует изменить, если log-файл находится в другом месте
maxretry = 3 #переопределяем значение, определенное в секции [DEFAULT]
[apache-overflows]
# блокировка на основании слишком длинных URL
enabled = true
port  = http,https
filter = apache-overflows
logpath = /var/log/apache*/*error.log #следует изменить, если log-файл находится в другом месте
maxretry = 2 #переопределяем значение, определенное в секции [DEFAULT]
[apache-badbots]
# блокировка "плохих" ботов
enabled  = true
port     = http,https
filter   = apache-badbots
logpath  = /var/log/apache*/*error.log
maxretry = 2

Для применения внесенных изменений следует перезапустить fail2ban:

/etc/init.d/fail2ban restart

Просмотреть какие jail’ы запущены в данный момент можно с помощью следующей команды:

fail2ban-client status
Status
|- Number of jail:  5
`- Jail list:       apache-overflows, apache-noscript, ssh, apache-badbots, apache

Также можно проверить состояние правил в файрволле командой iptables --list-rules или iptables -S:

iptables -S

-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N fail2ban-apache
-N fail2ban-apache-badbots
-N fail2ban-apache-noscript
-N fail2ban-apache-overflows
-N fail2ban-ssh
-A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-apache-badbots
-A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-apache-overflows
-A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-apache-noscript
-A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-apache
-A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh
-A fail2ban-apache -j RETURN
-A fail2ban-apache-badbots -j RETURN
-A fail2ban-apache-noscript -j RETURN
-A fail2ban-apache-overflows -j RETURN
-A fail2ban-ssh -s 116.31.116.10/32 -j DROP
-A fail2ban-ssh -j RETURN

Больше информации о работе конкретного jail’а можно передав в качестве параметра его имя, например так:

fail2ban-client status ssh
Status for the jail: ssh
|- filter
|  |- File list:    /var/log/auth.log
|  |- Currently failed: 0
|  `- Total failed: 12086
`- action
   |- Currently banned: 1
   |  `- IP list:   116.31.116.10
   `- Total banned: 1002

IP-адрес нарушителя разблокируется автоматически по истечению времени указанного в bantime, но можно разблокировать его вручную используя следующую команду:

fail2ban-client set ssh unbanip 116.31.116.10

На этом все, в следующей статье рассмотрим настройку связки Nginx + Fail2ban.

Добавить комментарий

  1. На практике при больших нагрузках как себя проявляет fail2ban при анализе логов apache2? Пробовал использовать для защиты от брутфорса пароля к серверу, нагрузку приличную давало, поэтому отказался от данной утилитки и сделал все «топорно» 🙂

    Да и тех же «badbots», ИМХО, проще через htaccess рубануть

    • Честно сказать, при реально больших нагрузках (+ если еще нужно защищать nginx/ssh/кастомные сервисы) fail2ban ведет себя крайне отвратительно. Например, при настроенных 7 jail’ах и при 300К уникальных посетителей в день fail2ban постоянно висит в тройке лидеров по использованию CPU

    • Евгений, буквально через пару часов после ответа на ваш вопрос я опять столкнулся с проблемами в работе fail2ban )))
      Дело в том, что практически для всех своих jail’ов помимо обычного banaction я еще использовал action=sendmail-whois-lines (при блокировке плохого ip-адреса присылать письмо с whois-информацией о ящике и строками лога). Данные whois fail2ban запрашивает из RIPE Database, а у них есть ограничение на количество таких запросов (1000 с одного ip в сутки). И вчера к 18:00 я уже исчерпал этот лимит, при блокировке новых ip-адресов fail2ban пытался получить информацию о них в RIPE Database, получал сообщение вида:

      %ERROR:201: access denied for мой_ip_адрес
      %
      % Queries from your IP address have passed the daily limit of controlled objects.
      % Access from your host has been temporarily denied.
      % For more information, see
      % http://www.ripe.net/data-tools/db/faq/faq-db/why-did-you-receive-the-error-201-access-denied
      

      и очень серьезно натуплял систему.
      Пришлось переделать action=sendmail-whois-lines на action=sendmail, после чего все заработало как надо

      • Спасибо за ответ 🙂 К счастью, сталкиваюсь с fail2ban сейчас очень редко, да и обычно использовал именно для «защиты» доступа к 22 порту. Да и есть ли смысл для таких больших порталов использовать его, не проще анализировать логи скриптом по крону?

        • Ну в больших проектах логов бывает столько, что их и не проанализируешь (nginx/apache/exim могут гигабайты инфы в день писать, и это не самое подробное логирование).

          Но для особо важных вещей можно настроить logstach+kibana+elasticsearch или хотя бы loganalyzer

          • Пока сталкивался с логами в пару сот Gb, но благо анализировать их не приходилось. А вот указанную связку для интереса попробую собрать