Зачем fail2ban нужен для asterisk?
Как Вам известно, asterisk является приложением (сервером) для IP-телефонии. То есть позволяет подключившимся к нему клиентам звонить друг другу и во внешний мир, используя (помимо всего прочего) линии телефонной связи. При этом возникают следующие риски:
- клиенты идентифицируются по логину/паролю, а также (как правило) по IP адресу. При этом существует возможность подобрать пароль (раньше или позже, в зависимости от его сложности, но в любом случае это возможно), причем крайне часто ограничения по IP адресам далеко не такие жесткие, как хотелось бы (в идеале для каждого клиента должен быть свой уникальный IP адрес)
- входящие звонки из интернета (например, с других серверов asterisk). С этими подключениями все сложнее, поскольку asterisk (в базовой конфигурации) не предусматривает отображение IP адресов, с которых производится подключение.
Программа fail2ban в связке с брандмауэром (например, iptables) и правильно настроенным asterisk (отображающим в логах полную информацию, в том числе IP адреса клиентов и других серверов) позволяет эффективно заблокировать попытки подключения и подбора пароля.
Перед началом настройки Вам необходимо установить iptables и fail2ban. Кроме того, iptables должен быть уже настроен (и разрешать подключения к asterisk) до начала настройки fail2ban! Прочитать, как настроить iptables можно здесь: настройка iptables для работы asterisk. Вы также можете установить fail2ban до установки самого asterisk, и в этом случае (по крайней мере, теоретически) в процессе установки последние версии asterisk обнаруживают установленный fail2ban и настраивают его автоматически. Однако:
- Не всегда вопрос безопасности IP-телефонии рассматривается до установки asterisk. То есть скорее всего, Вы захотите установить fail2ban на систему с уже установленным (и настроенным) астериском.
- Не во всех случаях автоматическое конфигурирование срабатывает вообще, не говоря уже о том, чтобы оно сработало правильно (и начало блокировать все атаки на asterisk).
Настройка ведения логов asterisk
В первую очередь имеет смысл настроить ведение логов asterisk, чтобы информация сразу же начала собираться в нужном нам формате и виде. Для этого в каталоге конфигурации asterisk (по умолчанию это /etc/asterisk) найдите файл logger.conf и внесите в него следующие изменения: раскомментируйте (уберите точку с запятой в начале строки):
dateformat=%F %T ; ISO 8601 date format
Это нужно для того, чтобы asterisk писал в логи дату в правильном формате:
год-месяц-день часы:минуты:секунды
Начиная с 10-й версии asterisk, Вы можете включить Asterisk Security Framework. Для этого в файле logger.conf найдите и раскомментируйте (или добавьте) строку:
security => security
В этой строке с левой стороны от стрелки указано имя файла, в котором будут сохраняться события, а с правой стороны – уровни (типы событий), которые будут сохраняться. В данном примере события, относящиеся к уровню security (и только они), будут сохраняться в файл с именем security в папке логов asterisk.
Разумеется, после внесения изменений необходимо, чтобы asterisk перечитал конфигурацию. Для этого можно либо перезагрузить сервис астериска, либо только конфигурацию логов (logger reload из asterisk CLI).
После этого в папке логов asterisk (по умолчанию /var/log/asterisk) появится файл с именем security. Не забудьте настроить ротацию логов для этого файла (так же, как и для остальных логов asterisk)!
Настройка правил фильтрации
Теперь нам необходимо создать фильтр, который будет извлекать из общего потока сообщений астериска потенциально опасные события (неверный логин/пароль, попытка входа с неразрешенного IP адреса, и т.д. и т.п.). При этом нам необходимо не только обнаруживать такие потенциально опасные события, но и вычленять оттуда IP адрес, с которого было выполнено действие. То есть мы не просто ищем определенные строки в файлах событий астериска, а настраиваем правила фильтрации.
Правила фильтрации можно прописать в файле /etc/fail2ban/filter.d/asterisk.conf. Вот образец содержимого этого файла:
# Fail2Ban configuration file # # # $Revision: 250 $ # [INCLUDES] # Read common prefixes. If any customizations available -- read them from # common.local #before = common.conf [Definition] #_daemon = asterisk # Option: failregex # Notes.: regex to match the password failures messages in the logfile. The # host must be matched by a group named "host". The tag "" can # be used for standard IP/hostname matching and is only an alias for # (?:::f{4,6}:)?(?PS+) # Values: TEXT # # Asterisk 1.8 uses Host:Port format which is reflected here failregex = NOTICE.* .*: Registration from '.*' failed for ':.*' - Wrong password NOTICE.* .*: Registration from '.*' failed for ':.*' - No matching peer found NOTICE.* .*: Registration from '.*' failed for ':.*' - Username/auth name mismatch NOTICE.* .*: Registration from '.*' failed for ':.*' - Device does not match ACL NOTICE.* .*: Registration from '.*' failed for ':.*' - Not a local domain NOTICE.* .*: Registration from '.*' failed for ':.*' - Peer is not supposed to register NOTICE.* .*: Registration from '.*' failed for ':.*' - ACL error (permit/deny) NOTICE.* .*: Registration from '.*' failed for '' - Wrong password NOTICE.* .*: Registration from '.*' failed for '' - No matching peer found NOTICE.* .*: Registration from '.*' failed for '' - Username/auth name mismatch NOTICE.* .*: Registration from '.*' failed for '' - Device does not match ACL NOTICE.* .*: Registration from '.*' failed for '' - Not a local domain NOTICE.* .*: Registration from '.*' failed for '' - Peer is not supposed to register NOTICE.* .*: Registration from '.*' failed for '' - ACL error (permit/deny) NOTICE.* .*: Registration from '".*".*' failed for ':.*' - No matching peer found NOTICE.* .*: Registration from '".*".*' failed for ':.*' - Wrong password NOTICE.* .*: No registration for peer '.*' (from ) NOTICE.* .*: Host failed MD5 authentication for '.*' (.*) NOTICE.* .*: Failed to authenticate user .*@.* NOTICE.* failed to authenticate as '.*'$ NOTICE.* .*: Sending fake auth rejection for device .*<sip:.*@>;tag=.* NOTICE.* .*: tried to authenticate with nonexistent user '.*' VERBOSE.*SIP/-.*Received incoming SIP connection from unknown peer # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. # Values: TEXT # ignoreregex =
В asterisk версии 1.4 и более ранних используются строки типа “… failed for ‘<HOST>’ …”, а в asterisk 1.8 и выше – строки “… failed for ‘<HOST>:.*’ …”, поскольку начиная с версии asterisk 1.8 в логах появилась информация о номере порта, которой нет в asterisk 1.4. Приведенный выше вариант учитывает как старые, так и новые версии asterisk, так что Вам нет необходимости в нем что-либо менять.
Для asterisk версии 10 и выше, если Вы включили ведение логов security, не забудьте прописать правила фильтрации для этих логов!
Правила фильтрации можно прописать в файле /etc/fail2ban/filter.d/asterisk-security.conf. Вот образец содержимого этого файла:
# Fail2Ban configuration file # # # $Revision: 250 $ # [INCLUDES] # Read common prefixes. If any customizations available -- read them from # common.local #before = common.conf [Definition] #_daemon = asterisk # Option: failregex # Notes.: regex to match the password failures messages in the logfile. The # host must be matched by a group named "host". The tag "" can # be used for standard IP/hostname matching and is only an alias for # (?:::f{4,6}:)?(?PS+) # Values: TEXT # failregex = SECURITY.* SecurityEvent="FailedACL".*RemoteAddress=".+?/.+?//.+?".* SECURITY.* SecurityEvent="InvalidAccountID".*RemoteAddress=".+?/.+?//.+?".* SECURITY.* SecurityEvent="ChallengeResponseFailed".*RemoteAddress=".+?/.+?//.+?".* SECURITY.* SecurityEvent="InvalidPassword".*RemoteAddress=".+?/.+?//.+?".* # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. # Values: TEXT # ignoreregex =
Настройка изоляторов (jails) для fail2ban
Теперь нам необходимо создать описания так называемых “изоляторов” (jails) для fail2ban, т.е. “привязать” наши фильтры к fail2ban: объяснить, в каких файлах эти строки искать, и что потом делать.
Для этого откройте файл /etc/fail2ban/jail.conf
- Убедитесь, что нет (или не включено) других правил, связанных с asterisk! Для этого достаточно сделать поиск по файлу по имени “asterisk” (без кавычек) и убедиться, что если такие правила есть, для каждого из них свойство enabled установлено в false:
enabled = false
- В случае, если версия asterisk меньше 10-й, либо Вы не хотите использовать логи security (использование логов security крайне рекомендуется), то Вам достаточно будет создать только одно правило. В противном случае Вам понадобится создать 2 правила.
Правило № 1
Это правило необходимо создать для всех версий asterisk. Вы можете создать новое правило, или модифицировать любое из уже имеющихся, но отключенных. Новое правило (поскольку в нашем примере используется fail2ban в связке с iptables) будет называться asterisk-iptables и будет применяться к файлу, в котором сохраняются все основные виды событий астериска (notice, warning, error, …). По умолчанию в астериске этот основной файл логов называется messages, но (например) в FreePBX это будет файл под названием full (как называется файл у Вас – см. настройки астериска в файле logger.conf). Итак, само правило:
# настраиваем изоляторы fail2ban для основных событий asterisk: [asterisk-iptables] # правило включено: enabled = true # фильтр, которым будет пользоваться правило, называется asterisk # (название фильтра - это имя файла в каталоге /etc/fail2ban/filter.d): filter = asterisk # к какому файлу (логам астериска) применять фильтр для поиска потенциально опасных событий: logpath = /var/log/asterisk/messages # количество потенциально опасных событий, найденных фильтром, для срабатывания действия: maxretry = 3 # на какой период времени (в секундах) применять действие action: bantime = 86400 # за какой период времени (в секундах) искать в logpath потенциально опасные события: findtime = 3600 # что делать, если фильтр обнаружил атаку (за период findtime секунд в логах logpath обнаружено # maxretry потенциально опасных действий с одного IP адреса) - блокируем все порты # для этого IP и посылаем письмо для root: action = iptables-allports[name=ASTERISK, protocol=all] sendmail-whois[name=ASTERISK, dest=root, sender=fail2ban@asterisk] # список IP адресов/подсетей, для которых все потенциально опасные события игнорируются: ignoreip = 127.0.0.1/8
Правило № 2
Это правило будет работать только в случае, если версия asterisk – 10 или новее, а также если включено ведение логов security (см. выше). Вы также можете создать новое правило, или модифицировать любое из уже имеющихся, но отключенных. Новое правило (поскольку в нашем примере используется fail2ban в связке с iptables) будет называться asterisk-security-iptables и это правило будет использовать для анализа файл security в каталоге логов астериска:
# настраиваем изоляторы fail2ban для событий безопасности asterisk: [asterisk-security-iptables] # правило включено: enabled = true # фильтр, которым будет пользоваться правило, называется asterisk-security # (название фильтра - это имя файла в каталоге /etc/fail2ban/filter.d): filter = asterisk-security # к какому файлу (логам астериска) применять фильтр для поиска потенциально опасных событий: logpath = /var/log/asterisk/security # количество потенциально опасных событий, найденных фильтром, для срабатывания действия: maxretry = 3 # на какой период времени (в секундах) применять действие action: bantime = 86400 # за какой период времени (в секундах) искать в logpath потенциально опасные события: findtime = 3600 # что делать, если фильтр обнаружил атаку (за период findtime секунд в логах logpath обнаружено # maxretry потенциально опасных действий с одного IP адреса) - блокируем все порты # для этого IP и посылаем письмо для root: action = iptables-allports[name=ASTERISK-security, protocol=all] sendmail-whois[name=ASTERISK-security, dest=root, sender=fail2ban@asterisk] # список IP адресов/подсетей, для которых все потенциально опасные события игнорируются: ignoreip = 127.0.0.1/8
Запуск fail2ban
Теперь необходимо запустить (или перезапустить) fail2ban и (если это необходимо, например iptables еще не был запущен) iptables.
Для запуска iptables (его нужно запустить первым) выполните следующую команду:
/etc/init.d/iptables start
Для перезапуска fail2ban выполните следующую команду:
/etc/init.d/fail2ban restart
Для проверки, что fail2ban запущен успешно и правило загружено, выполните следующую команду:
fail2ban-client status asterisk-iptables
и (если есть второе правило)
fail2ban-client status asterisk-security-iptables
Для отображения списка правил iptables выполните следующую команду:
iptables -L -n
В случае, если Вы только что установили fail2ban / iptables, не забудьте убедиться, что они настроены у Вас стартовать автоматически при загрузке системы!
Проверка работы fail2ban
Главное в процессе проверки fail2ban – иметь под рукой другой компьютер (или локальный доступ к серверу asterisk), чтобы в случае, когда fail2ban заблокирует Ваш IP адрес, Вы смогли подключиться и удалить эту блокировку!
Необходимо обязательно проверить работу связки fail2ban + iptables, поскольку, даже если Вы все настроили (или скопировали) правильно, возможно множество комбинаций событий, в результате которых настренные Вами блокировки работать не будут.
Последовательность действий для проверки работы связки fail2ban + iptables:
- Убедитесь, что у Вас настроен запуск iptables и fail2ban при старте компьютера
- Если Вы настроили 2 правила для fail2ban, настоятельно рекомендуем проверить работу каждого из них по отдельности. Для этого отключите одно из правил (
enabled = false
), например asterisk-security-iptables - перезагрузите компьютер и проверьте, что:
- службы iptables и fail2ban запущены:
service fail2ban status
service iptables status
- одно из правил включено, а другое – выключено:
fail2ban-client status asterisk-iptables
fail2ban-client status asterisk-security-iptables
При этом для выключенного правила появится сообщение:
Sorry but the jail 'asterisk-security-iptables' does not exist
,
а для включенного – сообщение вида:
Status for the jail: asterisk-iptables
|- filter
| |- File list: /var/log/asterisk/messages
| |- Currently failed: 0
| `- Total failed: 0
`- action
|- Currently banned: 0
`- Total banned: 0
- службы iptables и fail2ban запущены:
- Запустите SIP-клиент (обязательно не с самого сервера asterisk, а с другого компьютера!), и указав неверные данные для авторизации (IP адрес для подключения должен быть IP адресом сервера asterisk!), попробуйте авторизоваться 3 раза или более (количество авторизаций, после которых IP адрес блокируется, задается в параметре maxretry для каждого правила отдельно). В качестве тестового sip клиента можно использовать программу sipsak, которая работает из командной строки.
- Если Вы запустили SIP клиента с того же компьютера, с которого подключались к серверу asterisk, и если fail2ban + iptables были настроены правильно, то на данный момент Ваш IP адрес заблокирован, и Вы не можете подключиться к серверу asterisk с этого компьютера (проверьте это!). Подключитесь к asterisk с другого компьютера (или локально) и продолжайте выполнение команд.
- Запустите команду вида:
fail2ban-client status asterisk-iptables
для включенного правила, и убедитесь, что IP адрес, с которого подключался SIP клиент, находится в списке заблокированных IP (banned). - Теперь по аналогии с действиями из пункта 2 разблокируйте второе правило (например asterisk-security-iptables) и заблокируйте первое (asterisk-iptables).
- Выполните действия с пункта 3 по пункт 6, только вместо перезагрузки компьютера (что тоже можно сделать) достаточно перезагрузить службу fail2ban. После этого сразу разблокируется IP адрес компьютера, на котором Вы запускали SIP клиент, и его можно будет (и нужно, как в пункте 4) запустить еще раз – для проверки работы второго правила. Обратите внимание, что может и не разблокировать (точнее, разблокировать и снова заблокировать) – в этом случае Вам лучше сделать паузу findtime секунд, после чего еще раз перезагрузить сервис fail2ban.
- После того, как Вы проверили работу обоих правил по отдельности, не забудьте обязательно включить их оба (для asterisk-iptables и для asterisk-security-iptables параметр enabled = true). После этого, разумеется, не забудьте перезагрузить сервис fail2ban.
- И последний пункт: если Вы выполнили предыдущие пункты достаточно быстро (в течение нескольких минут), то может оказаться, что после включения обоих правил (и последующей перезагрузки fail2ban) у Вас снова заблокируется IP адрес, с которого Вы запускали SIP клиента.
Будьте внимательны!
Управление правилами fail2ban
Временное отключение блокировки IP адреса
Для этого Вам необходимо воспользоваться услугой iptables. Сначала мы выведем список правил на консоль, а затем выбрав нужные IP, удалим их из бана.
Для просмотра списка правил введите команду:
iptables -L -n
Вы увидите сообщение следующего вида:
Chain INPUT (policy ACCEPT)
target prot opt source destination
...
fail2ban-ASTERISK all -- 0.0.0.0/0 0.0.0.0/0
...
Chain fail2ban-ASTERISK
target prot opt source destination
DROP all -- 1.2.3.4 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
...
Нас интересует удалить из бана IP адрес 1.2.3.4, который (как мы видим) находится в цепочке правил (chain) под названием fail2ban-ASTERISK. Набираем команду:
iptables -D fail2ban-ASTERISK -s 1.2.3.4 -j DROP
В случае успешного выполнения команды никаких сообщений не появится, и если мы теперь снова запустим команду
iptables -L -n
то увидим, что IP адрес исчез из блокировки iptables (хотя и остался в блокировке fail2ban!). При этом мы снова можем подключаться к серверу asterisk
Постоянное отключение блокировки IP адреса
Для того, чтобы fail2ban не блокировал определенный IP адрес (или несколько IP адресов) независимо от того, сколько неудачных попыток подбора пароля (и прочих “неправомерных” действий) они совершили, необходимо произвести дополнительную настройку jails в файле /etc/fail2ban/jail.conf
В каждом правиле файла jail.conf может присутствовать параметр ignoreip, который задает список IP адресов, попадающих в “белый список” для этого правила. Поскольку правил у нас может быть два, обратите внимание, что Ваш IP необходимо прописывать в обоих правилах!
Параметр имеет следующий вид:
ignoreip = 127.0.0.1/8 192.168.0.0/16 1.2.3.4
То есть Вы можете прописывать как подсети, так и отдельные IP адреса (в данном случае в “белый список” попадают IP 127.0.0.1-127.0.0.255, 192.168.0.1-192.168.255.255 и 1.2.3.4).
Разблокировка IP адреса, с которого производилось тестирование
Во время проверки правильности настройки fail2ban Вы неоднократно запускали SIP клиента для тестирования работы по блокировке будущих атак из интернета. И в процессе последующей работы Вам, возможно, также понадобится время от времени производить действия, последствиями которых может быть блокировка со стороны fail2ban / iptables. Хотелось бы не дожидаться, когда fail2ban “соизволит” разблокировать IP сам (а это может быть довольно долго – поскольку параметр bantime можно выставить хоть на час, хоть на день, хоть на год).
Существуют 2 пути решения подобной проблемы:
- Внести IP адрес в правилах fail2ban в список ignoreip. Но иногда это может быть нежелательно (чтобы, например, производить периодическое тестирование работы fail2ban)
- Обычно время findtime (это длительность интервала в секундах, за которое событие [атака, подбор пароля] должно повториться maxretry раз, после чего бан вступит в силу) намного меньше, чем bantime (это время бана в секундах, по истечении которого IP адрес удаляется из списка заблокированных). Например, findtime выставляется в 10 минут, а bantime – час. Либо findtime – час, а bantime – день или даже больше. И так далее. Поэтому имеет смысл сделать паузу длительностью не менее, чем findtime с момента последнего тестирования (и забанивания Вашего IP адреса), после чего перезагрузить сервис fail2ban. При перезагрузке сервиса fail2ban все блокировки аннулируются. Однако при последующей загрузке fail2ban логи анализируются снова, и если в логах в течение findtime было maxretry неудачных попыток подключения с одного IP, этот IP будет снова забанен сразу после запуска fail2ban.
Тестирование конфигурации fail2ban
Вы можете проверить, как будет применяться фильтр fail2ban к тому или иному логу. Для этого можно запустить команду:
fail2ban-regex /var/log/asterisk/messages /etc/fail2ban/filter.d/asterisk.conf
Где /var/log/asterisk/messages – это пример пути к файлу с логами, который будет фильтроваться, а /etc/fail2ban/filter.d/asterisk.conf – сам фильтр, который содержит те фрагменты [сообщения об ошибках], которые должны быть в логе [чтобы забанить IP адреса атакующих].
И напоследок: вместо перезагрузки fail2ban с помощью service fail2ban restart
можно выполнить следующую команду fail2ban-client reload