Поиск по сайту:

Как Fail2Ban работает для защиты служб на сервере Linux


Введение

SSH — это де-факто метод подключения к облачному серверу. Он надежен и расширяем — по мере разработки новых стандартов шифрования их можно использовать для создания новых ключей SSH, гарантируя, что основной протокол останется безопасным. Однако ни один протокол или программный стек не является полностью надежным, а широкое распространение SSH в Интернете означает, что он представляет собой очень предсказуемую поверхность атаки или вектор атаки, через которую люди могут попробуй получить доступ.

Таким образом, любая служба, доступная в сети, является потенциальной целью. Если вы просмотрите журналы для вашей службы SSH, работающей на любом сервере с большим трафиком, вы часто увидите повторяющиеся, систематические попытки входа в систему, которые представляют собой атаки методом перебора со стороны пользователей и ботов. Хотя вы можете внести некоторые оптимизации в свою службу SSH, чтобы снизить вероятность успеха этих атак почти до нуля, например, отключить аутентификацию по паролю в пользу ключей SSH, они все равно могут представлять собой небольшую постоянную ответственность.

Крупномасштабные производственные развертывания, для которых эта ответственность совершенно неприемлема, обычно реализуют VPN, такую как WireGuard, перед своей службой SSH, поэтому невозможно напрямую подключиться к SSH-порту 22 по умолчанию из внешнего Интернета без дополнительной программной абстракции или шлюзы. Этим VPN-решениям доверяют многие, но они добавят сложности и могут сломать некоторые средства автоматизации или другие небольшие программные ловушки.

До или в дополнение к полной настройке VPN вы можете внедрить инструмент под названием Fail2ban. Fail2ban может значительно смягчить атаки грубой силы, создавая правила, которые автоматически изменяют конфигурацию вашего брандмауэра, чтобы запретить определенные IP-адреса после определенного количества неудачных попыток входа в систему. Это позволит вашему серверу защитить себя от этих попыток доступа без вашего вмешательства.

В другом уроке мы обсуждали, как защитить SSH с помощью Fail2ban. В этом руководстве мы более подробно обсудим, как на самом деле работает Fail2ban и как вы можете использовать эти знания для изменения или расширения поведения этой службы.

Основы Fail2ban

Целью Fail2ban является мониторинг журналов общих служб для выявления закономерностей сбоев аутентификации.

Когда fail2ban настроен на мониторинг журналов службы, он просматривает фильтр, настроенный специально для этой службы. Фильтр предназначен для выявления ошибок аутентификации для этой конкретной службы с помощью сложных регулярных выражений. Регулярные выражения — это распространенный язык шаблонов, используемый для сопоставления с образцом. Он определяет эти шаблоны регулярных выражений во внутренней переменной с именем failregex.

По умолчанию Fail2ban включает файлы фильтров для общих служб. Когда журнал какой-либо службы, например веб-сервера, соответствует failregex в своем фильтре, для этой службы выполняется предопределенное действие. action — это переменная, которую можно настроить для выполнения множества различных действий в зависимости от предпочтений администратора.

Действие по умолчанию — запретить нарушающий хост/IP-адрес, изменив правила локального брандмауэра. Вы можете расширить это действие, например, отправить электронное письмо системному администратору.

По умолчанию действие будет предпринято при обнаружении трех сбоев аутентификации в течение 10 минут, а время бана по умолчанию составляет 10 минут. Это настраивается.

При использовании брандмауэра iptables по умолчанию fail2ban создает новый набор правил брандмауэра, также называемый цепочкой, при запуске службы. Он добавляет новое правило в цепочку INPUT, которое отправляет весь TCP-трафик, направленный на порт 22, в новую цепочку. В новую цепочку вставляется одно правило, которое возвращается в цепочку INPUT. Цепочка и связанные с ней правила удаляются, если служба Fail2ban остановлена.

Изучение настроек службы Fail2ban

Fail2ban настраивается с помощью нескольких файлов, расположенных в иерархии в каталоге /etc/fail2ban/.

Файл fail2ban.conf настраивает некоторые рабочие параметры, такие как способ, которым демон регистрирует информацию, а также сокет и файл pid, которые он будет использовать. Однако основная конфигурация указана в файлах, определяющих «тюрьмы» для каждого приложения.

По умолчанию fail2ban поставляется с файлом jail.conf. Однако это может быть перезаписано в обновлениях, поэтому вам следует скопировать этот файл в файл jail.local и внести изменения там.

Если у вас уже есть файл jail.local, откройте его с помощью nano или вашего любимого текстового редактора:

  1. sudo nano /etc/fail2ban/jail.local

Если у вас еще нет файла jail.local или вы открыли пустой файл, скопируйте файл jail.conf и откройте новый файл:

  1. sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
  2. sudo nano /etc/fail2ban/jail.local

Мы рассмотрим доступные здесь параметры и посмотрим, как этот файл взаимодействует с другими файлами конфигурации в системе.

Раздел по умолчанию

Первая часть файла будет определять значения по умолчанию для политики fail2ban. Эти параметры можно переопределить в разделе конфигурации каждой отдельной службы.

После удаления комментариев весь раздел по умолчанию выглядит примерно так:

[DEFAULT]

ignoreip = 127.0.0.1/8
bantime = 10m
findtime = 10m
maxretry = 3
backend = auto
usedns = warn
destemail = root@localhost
sendername = Fail2Ban
banaction = iptables-multiport
mta = sendmail
protocol = tcp
chain = INPUT
action_ = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
action_mw = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
            %(mta)s-whois[name=%(__name__)s, dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s", sendername="%(sendername)s"]
action_mwl = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
            %(mta)s-whois-lines[name=%(__name__)s, dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s", sendername="%(sendername)s"]
action = %(action_)s

Давайте рассмотрим, что это означает:

  • ignoreip: этот параметр определяет IP-адреса, которые должны игнорироваться системой блокировки. По умолчанию это просто настроено на игнорирование трафика, исходящего от самой машины, чтобы вы не заполняли свои собственные журналы и не блокировали себя.
  • bantime: этот параметр устанавливает продолжительность бана в секундах. По умолчанию – 10 минут.
  • findtime: этот параметр устанавливает окно, на которое Fail2ban будет обращать внимание при поиске повторных неудачных попыток аутентификации. По умолчанию установлено значение 10 минут, что означает, что программа будет подсчитывать количество неудачных попыток за последние 10 минут.
  • maxretry: задает допустимое количество неудачных попыток в течение окна findtime, прежде чем будет наложен запрет.
  • backend: эта запись указывает, как Fail2ban будет отслеживать файлы журналов. Настройка auto означает, что fail2ban попытается использовать pyinotify, затем gamin, а затем алгоритм опроса на основе того, что доступно. inotify — это встроенная функция ядра Linux для отслеживания доступа к файлам, а pyinotify — это интерфейс Python для inotify, используемый Fail2ban.
  • usedns: определяет, используется ли обратный DNS для реализации запретов. Если задать для этого параметра значение \no, будут заблокированы сами IP-адреса, а не их имена хостов в домене. Параметр warn попытается найти имя хоста и заблокировать таким образом, но активность будет зарегистрирована для проверки.
  • destemail: это адрес, на который будут отправляться уведомления по электронной почте, если ваше действие настроено на отправку уведомлений по почте.
  • имя отправителя: будет использоваться в поле электронной почты от для сгенерированных электронных писем с уведомлениями.
  • banaction: устанавливает действие, которое будет использоваться при достижении порога. На самом деле это путь к файлу, расположенному в /etc/fail2ban/action.d/ и называемому iptables-multiport.conf. Это обрабатывает фактические манипуляции с брандмауэром iptables для блокировки IP-адреса. Мы рассмотрим это позже.
  • mta: это агент передачи почты, который будет использоваться для отправки уведомлений по электронной почте.
  • протокол: это тип трафика, который будет отбрасываться при блокировке IP-адресов. Это также тип трафика, который отправляется в новую цепочку iptables.
  • цепочка: это цепочка, в которой будет настроено правило перехода для отправки трафика в воронку fail2ban.

Остальные параметры определяют различные действия, которые можно указать. Они передают некоторые из параметров, которые мы определили выше, используя подстановку переменных в текстовых строках, например:

%(var_name)s

Строка выше будет заменена содержимым var_name. Используя это, мы можем сказать, что переменная action по умолчанию установлена в определение action_ (только бан, без почтовых оповещений).

Это, в свою очередь, настраивается вызовом действия iptables-multiport со списком параметров (имя службы, порт, протокол и цепочка), необходимых для выполнения бана. __name__ заменяется именем службы, как указано в заголовках разделов ниже.

Специальные разделы услуг

Под разделом по умолчанию находятся разделы для конкретных служб, которые можно использовать для переопределения настроек по умолчанию. Это соответствует соглашению об изменении только тех параметров, которые отличаются от нормальных значений (соглашение важнее конфигурации).

Заголовок каждого раздела указывается следующим образом:

[имя_службы]

Любой раздел, в котором есть строка enabled=true, будет прочитан и активирован.

В каждом разделе настраиваются параметры, в том числе файл фильтра, который следует использовать для анализа журналов (без расширения файла), и расположение самих файлов журналов.

Имея это в виду, раздел, определяющий действия для службы SSH, выглядит следующим образом:

[SSH]

enabled     = true
port        = ssh
filter      = sshd
logpath     = /var/log/auth.log
maxretry    = 6

Это включает этот раздел и устанавливает порт на порт по умолчанию \ssh (порт 22). Это говорит Fail2ban просмотреть журнал, расположенный в /var/log/auth.log для этого раздела и для анализа журнала с использованием механизмов фильтрации, определенных в каталоге /etc/fail2ban/filters.d в файле с именем sshd.conf.

Вся остальная необходимая информация берется из параметров, определенных в разделе [DEFAULT]. Например, для действия будет задано значение action_, которое заблокирует нарушающий IP-адрес с помощью действия блокировки iptables-multiport, которое ссылается на файл с именем iptables-multiport. conf, найденный в /etc/fail2ban/action.d.

Как видите, действия в разделе [DEFAULT] должны быть общими и гибкими. Использование подстановки параметров вместе с параметрами, которые обеспечивают разумные значения по умолчанию, позволит при необходимости переопределить определения.

Изучение файла фильтра

Чтобы понять, что происходит в нашей конфигурации, нам нужно понять файлы фильтров и действий, которые выполняют основную часть работы.

Файл фильтра определяет строки, которые fail2ban будет искать в лог-файлах, чтобы идентифицировать оскорбительные характеристики. Файл действий реализует все необходимые действия, от создания структуры брандмауэра при запуске службы до добавления и удаления правил и разрушения структуры брандмауэра при остановке службы.

Давайте посмотрим на файл фильтра, который вызвала наша служба SSH в приведенной выше конфигурации:

  1. sudo nano /etc/fail2ban/filter.d/sshd.conf
[INCLUDES]

before = common.conf

[Definition]

_daemon = sshd
failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error) for .* from <HOST>( via \S+)?\s*$
        ^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>\s*$
        ^%(__prefix_line)sFailed \S+ for .*? from <HOST>(?: port \d*)?(?: ssh\d*)?(: (ruser .*|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".*", client host ".*")?))?\s*$
        ^%(__prefix_line)sROOT LOGIN REFUSED.* FROM <HOST>\s*$
        ^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from <HOST>\s*$
        ^%(__prefix_line)sUser .+ from <HOST> not allowed because not listed in AllowUsers\s*$
        ^%(__prefix_line)sUser .+ from <HOST> not allowed because listed in DenyUsers\s*$
        ^%(__prefix_line)sUser .+ from <HOST> not allowed because not in any group\s*$
        ^%(__prefix_line)srefused connect from \S+ \(<HOST>\)\s*$
        ^%(__prefix_line)sUser .+ from <HOST> not allowed because a group is listed in DenyGroups\s*$
        ^%(__prefix_line)sUser .+ from <HOST> not allowed because none of user's groups are listed in AllowGroups\s*$
ignoreregex =

Заголовок раздела [INCLUDES] указывает другие файлы фильтров, которые считываются до или после этого файла. В нашем примере файл common.conf считывается и помещается перед другими строками в этом файле. Это устанавливает некоторые параметры, которые мы будем использовать в нашей конфигурации.

Далее у нас есть раздел [Definition], который определяет фактические правила для совпадений нашего фильтра. Во-первых, мы устанавливаем имя демона, за которым следим, используя параметр _daemon.

После этого мы проходим через фактическое определение failregex, которое устанавливает шаблоны, которые будут запускаться при обнаружении соответствующей строки в файле журнала. Это регулярные выражения, которые сопоставляются на основе различных ошибок и сбоев, которые могут возникать, когда пользователь не проходит проверку подлинности правильно.

Части строки, такие как %(__prefix_line)s, будут заменены значением настройки параметра в файле common.conf, который мы получили. Это используется для сопоставления различной ведущей информации, которую операционные системы записывают в файлы журнала, когда они используют стандартные методы. Например, некоторые строки из /var/log/auth.log могут выглядеть примерно так:

May  6 18:18:52 localhost sshd[3534]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=101.79.130.213 
May  6 18:18:54 localhost sshd[3534]: Failed password for invalid user phil from 101.79.130.213 port 38354 ssh2
May  6 18:18:54 localhost sshd[3534]: Received disconnect from 101.79.130.213: 11: Bye Bye [preauth]

Выделенная часть — это стандартный шаблон, который вставляет операционная система, чтобы предоставить больше контекста. После этого существует довольно много разных способов, которыми служба брандмауэра iptables записывает попытки сбоя в журнал.

Мы видим две отдельные ошибки в первых двух строках выше (ошибка аутентификации PAM и ошибка пароля). Регулярные выражения, определенные в фильтре, предназначены для соответствия любой из возможных строк отказа. Вам не нужно настраивать какие-либо из этих строк, но вы должны знать о необходимости перехватывать все записи журнала, которые означают ошибку несанкционированного использования для приложения, которое вы пытаетесь защитить, если вам когда-либо придется создавать файл фильтра самостоятельно. .

Внизу вы можете увидеть параметр ignoreregex, который в настоящее время пуст. Это можно использовать для исключения более конкретных шаблонов, которые обычно соответствуют условию сбоя, если вы хотите отменить триггер сбоя для fail2ban для определенных сценариев. Мы не будем это корректировать.

Сохраните и закройте файл, когда закончите его изучение.

Изучение файла действий

Теперь давайте посмотрим на файл действия. Этот файл отвечает за настройку брандмауэра со структурой, позволяющей вносить изменения для запрета вредоносных хостов, а также для добавления и удаления этих хостов по мере необходимости.

Действие, которое вызывает наша служба SSH, называется iptables-multiport. Откройте связанный файл сейчас:

  1. sudo nano /etc/fail2ban/action.d/iptables-multiport.conf

С удаленными комментариями этот файл выглядит примерно так:

[INCLUDES]
before = iptables-blocktype.conf

[Definition]
actionstart = iptables -N fail2ban-<name>
                iptables -A fail2ban-<name> -j RETURN
                iptables -I <chain> -p <protocol> -m multiport --dports <port> -j fail2ban-<name>

actionstop = iptables -D <chain> -p <protocol> -m multiport --dports <port> -j fail2ban-<name>

actioncheck = iptables -n -L <chain> | grep -a 'fail2ban-<name>[ \t]'

actionban = iptables -I fail2ban-<name> 1 -s <ip> -j <blocktype>

actionunban = iptables -D fail2ban-<name> -s <ip> -j <blocktype>

[Init]
name = default
port = ssh
protocol = tcp
chain = INPUT

Файл начинается с поиска другого файла действий с именем iptables-blocktype.conf, который определяет параметр blocktype, который настраивает ограничение, которое будет установлено при блокировке клиента. По умолчанию blocktype настроен на отклонение пакетов и ответ на эхо-запросы, отправленные запрещенными клиентами, с сообщением об отклонении, что порт недоступен. Мы будем использовать это в наших правилах бана ниже.

Далее мы переходим к самим определениям правил. Действие actionstart устанавливает брандмауэр iptables при запуске службы fail2ban. Он создает новую цепочку, добавляет в эту цепочку правило для возврата в вызывающую цепочку, а затем вставляет правило в начало цепочки INPUT, которое пропускает трафик, соответствующий правильному протоколу и назначениям портов, в новую цепочку.

Это делается с помощью значений, которые мы передали с помощью action, которые мы определили в нашем файле jail.local. название берется из заголовка раздела для каждой службы. chain, protocol и port берутся из самой строки action в этом файле.

Здесь на все параметры, заданные другим файлом, ссылаются путем включения имени параметра в угловые скобки:

<имя_параметра>

Когда мы перейдем к сопутствующему определению actionstop, мы увидим, что команды брандмауэра реализуют обратную команду actionstart. Когда служба Fail2ban останавливается, она полностью удаляет все добавленные правила брандмауэра.

Другое действие, называемое actioncheck, проверяет, была ли создана правильная цепочка, прежде чем пытаться добавить правила запрета.

Далее мы переходим к фактическому правилу блокировки, которое называется actionban. Это правило работает, добавляя новое правило в нашу созданную цепочку. Правило соответствует исходному IP-адресу клиента-нарушителя — этот параметр считывается из журналов авторизации при достижении лимита maxretry. Он устанавливает блок, определенный параметром blocktype, который мы получили в разделе [INCLUDE] вверху файла.

Правило actionunban удаляет это правило. Это делается автоматически fail2ban по истечении времени бана.

Наконец, мы добираемся до раздела [Init]. Это просто предоставляет некоторые значения по умолчанию на случай, если файл действия вызывается без передачи всех соответствующих значений.

Как служба Fail2ban обрабатывает файлы конфигурации для реализации банов

Теперь, когда мы увидели особенности, давайте рассмотрим процесс, который происходит при запуске fail2ban.

Загрузка файлов начальной конфигурации

Сначала читается основной файл fail2ban.conf, чтобы определить условия, в которых должен работать основной процесс. При необходимости он создает файлы сокетов, pid и журналов и начинает их использовать.

Затем fail2ban считывает файл jail.conf для получения сведений о конфигурации. Далее следует чтение в алфавитном порядке всех файлов, найденных в каталоге jail.d, которые заканчиваются на .conf. Он добавляет настройки, найденные в этих файлах, в свою внутреннюю конфигурацию, отдавая предпочтение новым значениям по сравнению со значениями, описанными в файле jail.conf.

Затем он ищет файл jail.local и повторяет этот процесс, адаптируя новые значения. Наконец, он снова ищет в каталоге jail.d, читая в алфавитном порядке файлы, оканчивающиеся на .local.

В нашем случае у нас есть только файл jail.conf и файл jail.local. В нашем файле jail.local нам нужно только определить значения, которые отличаются от файла jail.conf. Процесс fail2ban теперь имеет набор директив, загруженных в память, которые представляют собой комбинацию всех найденных файлов.

Он проверяет каждый раздел и ищет директиву enabled=true. Если он его находит, он использует параметры, определенные в этом разделе, для построения политики и определения необходимых действий. Любые параметры, отсутствующие в разделе службы, используют параметры, определенные в разделе [DEFAULT].

Разбор файлов действий для определения начальных действий

Fail2ban ищет директиву action, чтобы выяснить, какой сценарий действия вызывать для реализации политик запрета/разбана. Если он не найден, он возвращается к действию по умолчанию, определенному выше.

Директива действия состоит из имени файла(ов) действия, которые будут прочитаны, а также словаря ключ-значение, который передает параметры, необходимые этим файлам. Их значения часто принимают форму подстановки параметров, ссылаясь на настройки, настроенные в разделе службы. Ключу \name обычно передается значение специальной переменной __name__, которой будет присвоено значение заголовка раздела.

Затем Fail2ban использует эту информацию для поиска связанных файлов в каталоге action.d. Сначала он ищет связанный файл действия, оканчивающийся на .conf, а затем дополняет найденную там информацию любыми настройками, содержащимися в сопровождающем файле .local, который также находится в . каталог action.d.

Он анализирует эти файлы, чтобы определить действия, которые необходимо предпринять. Он считывает значение actionstart, чтобы увидеть действия, которые необходимо предпринять для настройки среды. Это часто включает в себя создание структуры брандмауэра для соблюдения правил запрета в будущем.

Действия, определенные в этом файле, используют параметры, переданные ему из директивы action. Он будет использовать эти значения для динамического создания соответствующих правил. Если определенная переменная не была установлена, она может просмотреть значения по умолчанию, установленные в файле действий, чтобы заполнить пробелы.

Разбор файлов фильтров для определения правил фильтрации

Параметры службы в файлах jail.* также включают расположение файла журнала, а также механизм опроса, который следует использовать для проверки файла (это определяется параметр). Он также включает фильтр, который следует использовать, чтобы определить, представляет ли строка в журнале сбой.

Fail2ban ищет в каталоге filter.d соответствующий файл фильтра, оканчивающийся на .conf. Он читает этот файл, чтобы определить шаблоны, которые можно использовать для сопоставления строк-нарушителей. Затем он ищет соответствующий файл фильтра, оканчивающийся на .local, чтобы проверить, не были ли перезаписаны какие-либо параметры по умолчанию.

Он использует регулярные выражения, определенные в этих файлах, при чтении файла журнала службы. Он проверяет каждую строку failregex, определенную в файлах filter.d, с каждой новой строкой, записанной в файл журнала службы.

Если регулярное выражение возвращает совпадение, оно сравнивает строку с регулярными выражениями, определенными ignoreregex. Если это также совпадает, fail2ban игнорирует его. Если строка соответствует выражению в failregex, но не соответствует выражению в ignoreregex, внутренний счетчик увеличивается для клиента, вызвавшего строку, и связанная метка времени создан для мероприятия.

По мере достижения временного окна, заданного параметром findtime в файлах jail.* (что определяется отметкой времени события), внутренний счетчик снова уменьшается, и событие больше не считается относящимся к политике запрета.

Если с течением времени регистрируются дополнительные ошибки аутентификации, каждая попытка увеличивает значение счетчика. Если счетчик достигает значения, установленного параметром maxretry в течение настроенного временного окна, fail2ban вводит запрет, вызывая действие actioncheck для службы, как определено в action.d/ для службы. Это делается для того, чтобы определить, установила ли действие actionstart необходимую структуру. Затем он вызывает действие actionban для блокировки клиента-нарушителя. Он также устанавливает метку времени для этого события.

По истечении времени, указанного параметром bantime, fail2ban разблокирует клиента, вызвав действие actionunban.

Заключение

К настоящему моменту у вас есть довольно глубокое понимание того, как работает fail2ban. Когда вы отклоняетесь от стандартной конфигурации, полезно знать, как работает fail2ban, чтобы управлять его поведением предсказуемым образом.

Чтобы узнать, как защитить другие службы с помощью fail2ban, вы можете прочитать Как защитить сервер Nginx с помощью Fail2Ban в Ubuntu 22.04.