Как fail2ban защищает сервисы Linux

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

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

Сервис fail2ban динамически корректирует правила брандмауэра, чтобы заблокировать адреса, которые безуспешно пытаются войти в систему определенное количество раз.

Читайте также: Защита SSH с помощью fail2ban в Ubuntu 14.04

В этом мануале вы узнаете, как работает fail2ban и как управлять поведением этого сервиса.

1: Общие сведения

Основная идея fail2ban заключается в отслеживании логов общих сервисов для выявления ошибок аутентификации.

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

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

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

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

По умолчанию fail2ban блокирует адрес на 10 минут в случае обнаружения трех неудачных попыток авторизации в течение 10 минут. Количество неудачных попыток аутентификации, необходимое для блокировки адреса, переопределяется в разделе SSH конфигурационного файла по умолчанию – он разрешает до 6 попыток. Администратор может настроить этот параметр самостоятельно.

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

Это заставляет трафик прыгать в новую цепочку, а затем возвращаться обратно. Сначала это не влияет на трафик. Однако когда IP-адрес превышает количество попыток аутентификации, в начало новой цепочки добавляется правило, которое будет сбрасывать трафик от этого IP-адреса. Когда срок блокировки истечет, правило iptables будет удалено. Цепочка и связанные с ней правила удаляются при выходе из fail2ban.

2: Параметры fail2ban

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

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

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

Если у вас есть файл jail.local, откройте его:

sudo nano /etc/fail2ban/jail.local

Если у вас пока нет файла jail.local (или же открытый вами файл оказался пуст), скопируйте файл jail.conf в jail.local и откройте его:

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

Это поместит в копию файла все доступные опции стандартного конфигурационного файла.

Раздел DEFAULT

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

Без комментариев раздел DEFAULT выглядит примерно так:

[DEFAULT]
ignoreip = 127.0.0.1/8
bantime = 600
findtime = 600
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-адрес, чьи ошибки fail2ban будет игнорировать. По умолчанию этот параметр позволяет игнорировать трафик текущей машины.
  • bantime: этот параметр устанавливает продолжительнось блокировки в секундах. Значение по умолчанию – 600 секунд (10 минут).
  • findtime: этот параметр определяет интервал времени, в течение которого fail2ban будет отслеживать неудачные попытки аутентификации, исходящие от каждого адреса. По умолчанию установлено значение 600 секунд (еще 10 минут) – то есть, программное обеспечение будет подсчитывать количество неудачных попыток входа за последние 10 минут.
  • maxretry: определяет количество неудачных попыток входа для каждого адреса в течение времени, заданном в findtime.
  • backend: определяет, как fail2ban будет контролировать логи. Настройка auto означает, что fail2ban будет пробовать pyinotify, затем gamin, а затем алгоритм опроса, основанный на доступных данных.
  • usedns: определяет, используется ли в блокировке обратный DNS. Если параметр имеет значение no, fail2ban будет блокировать IP-адреса вместо имен хостов. Значение warn попытается использовать обратный DNS для поиска имени хоста и его блокировки, но будет регистрировать активность в логе.
  • destemail: это адрес, на который будет отправлено уведомление (если fail2ban поддерживает оповещения по почте).
  • sendername: это имя будет использоваться при отправке генерируемых уведомлений
  • banaction: устанавливает действие, которое будет использоваться при достижении порогового значения maxretry. В /etc/fail2ban/action.d/ есть файл iptables-multiport.conf. Он обрабатывает действия iptables, чтобы запретить вредоносный IP-адрес. Мы вернемся к этому файлу позже.
  • mta: агент передачи почты, который будет использоваться для отправки уведомлений.
  • protocol: тип трафика, который будет сбрасываться при блокировке IP. Это также тип трафика, который отправляется в новую цепочку iptables.
  • chain: Это цепочка, которая будет настроена для отправки трафика в последовательность fail2ban.

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

%(var_name)s

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

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

Разделы сервисов

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

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

[service_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.

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

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

3: Фильтры

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

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

Рассмотрим фильтр сервиса SSH:

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

4: Действия

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

Как помните, сервис SSH использует для этого файл iptables-multiport. Откройте его:

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 сбрасывает пакеты и отвечает на команду ping, отправленную заблокированными клиентами, сообщением об отказе (порт недоступен). Это можно использовать в правилах блокировки далее.

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

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

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

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

<param_name>

Определение actionstop позволяет брандмауэру отменить команды actionstart. Оно удаляет структуру брандмауэра, когда сервис fail2ban останавливается.

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

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

Правило actionunban просто удаляет предыдущее правило. fail2ban делает это автоматически, когда время блокировки истекает.

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

5: Обработка конфигурационных файлов fail2ban

Загрузка исходных конфигурационных файлов

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

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

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

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

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

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

Обработка файлов действий

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

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

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

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

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

Обработка фильтров

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

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

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

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

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

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

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

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

Заключение

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

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

Читайте также:

Tags: ,