Хабрахабр

Использование базы данных лога Mikrotik для пресечения брутфорса

Добрый день.

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

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

Цель: Динамическое управление правилами фаервола Микротик для пресечения сетевых атак с перебором пароля.

Средства: Свежий дистрибутив Linux с rsyslogd v8, crond, СУБД mariadb и собственно сам маршрутизатор Микротик.

Это могут быть входящие на Микротик и пробрасываемые в локальную сеть порты. Механика: С помощью назначенного задания, выполняется SQL запрос в БД с накопленными и пополняемыми данными трафика и возвращает список исходящих ip-адресов, запускаемый кроном bash скрипт формирует команды Микротика и с помощью ssh соединения, пополняет список адресов для имеющихся правил блокировки.
Речь пойдет о защите открытых TCP портов.

Для начала обозначим где могут быть слабые места:

  • Управляющие протоколы маршрутизатора ssh, telnet, web, winbox
  • Почтовые службы smtp, pop, imap
  • Любые веб сервисы предоставляемые наружу
  • Удаленный рабочий стол MS RDP, VNC и т.д.
  • Что-либо другое, на ваше усмотрение

Пишем запрос SQL для поиска брутфорсера

По этому префиксу мы и будем производить поиск: В нашей организации есть терминальные серверы открытые наружу по не приоритетным портам.
В DNAT Микротика я включил логгирование необходимых правил добавив префикс RDP_DNAT.

MariaDB [traflog]> select src,dport,count(dport) as 'попытки подключения' from traffic where datetime>now() - interval 1 day and logpref='RDP_DNAT' group by src having count(dport)>50;
+-----------------+-------+---------------------------------------+
| src | dport | попытки подключения |
+-----------------+-------+---------------------------------------+
| 185.156.177.58 | 12345 | 118 |
| 185.156.177.59 | 12345 | 267 |
| 193.238.46.12 | 12345 | 318 |
| 193.238.46.13 | 12345 | 319 |
| 193.238.46.99 | 12345 | 342 |
| 194.113.106.150 | 12345 | 67 |
| 194.113.106.152 | 12345 | 167 |
| 194.113.106.153 | 12345 | 190 |
| 194.113.106.154 | 12345 | 192 |
| 194.113.106.155 | 12345 | 190 |
| 194.113.106.156 | 12345 | 216 |
| 194.113.106.158 | 12345 | 124 |
+-----------------+-------+---------------------------------------+
12 rows in set (0.06 sec)

Этот запрос показывает ip адрес (с которого идет атака), порт на который происходит подключение (номер порта изменен) и количество попыток подключения, с предварительной группировкой по src и выборкой строк, с количеством попыток более 50 за прошедшие, от текущего момента, сутки.

В моем случае, эти адреса можно смело банить, так как количество подключений у «хороших» клиентов меньше, не более 5-10 в сутки с одного ip.

Для дальнейшего использования я предлагаю сделать представление (view), что бы в будущем меньше копипастить: Запрос работает нормально, быстро, но он длинноват.

MariaDB [traflog]> create or replace view rdp_brute_day as select src, dport, count(dport) from traffic where datetime>now() - interval 1 day and logpref='RDP_DNAT' group by src having count(dport)>50;
Query OK, 0 rows affected (0.23 sec)

Проверим как работает вьюшка:

MariaDB [traflog]> select src,count(dport) from rdp_brute_day;
+----------------+--------------+
| src | count(dport) |
+----------------+--------------+
| 185.156.177.58 | 11 |
+----------------+--------------+
1 row in set (0.09 sec)

Отлично.

Добавляем пользователя Микротик с авторизацией по ключу dsa

В консоли linux генерируем ключ dsa, под пользователем, от имени которого будет запускаться назначенное задание, я делал из под root:

root@monix:~# ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/root/.ssh/id_dsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_dsa.
Your public key has been saved in /root/.ssh/id_dsa.pub.
...

Passphrase назначать не надо. Публичный ключ /root/.ssh/id_dsa.pub копируем на Микротик любым доступным способом. Я вывел его командой cat, скопировал текст из окна putty в текстовый файл, сохранился и перетащил в окно winbox files.

При подключении с сервера через ssh, Микротик запрашивал у меня еще и пароль. Не знаю почему, но при выполнении следующих операций через интерфейс winbox что-то пошло не так. Делал примерно, как описано тут. После того, как удалил созданного пользователя и выполнил все операции через консоль, подключение по dsa заработало.

В общем я получил желанный вход без пароля по ключу dsa и выполнил проверочную команду:

root@monix:/# ssh rsyslogger@192.168.0.230 /system resource print uptime: 2w1d5h22m43s version: 6.43.2 (stable)
...

Хорошо.

Пишем bash скрипт

Скрипт получился не сложный:

mikrotik_cmd_list() mikrotik_cmd_list | ssh rsyslogger@192.168.0.230

Для того чтобы передать все команды в рамках одного ssh соединения, мне понадобилось описать функцию mikrotik_cmd_list(), в которой сначала выполняется запрос с сохранением ip адресов в переменную brute_src_list, далее в цикле эта переменная последовательно формирует команды для Микротика. После вызова функции, вывод направляется через трубу в ssh.

Если хотите оставить его навсегда, уберите опцию timeout. Не забываем закрыть права доступа к скрипту всем кроме root и делаем файл исполняемым.
Команда которую генерирует скрипт, добавит ip адрес в rdp_banlist на 1 день, по истечении этого времени он сам удалится из списка.

Добавляем правило в фаервол

Я придумал два варианта, как использовать список rdp_banlist:

Вариант первый: добавить список rdp_banlist с восклицательным знаком в правила NAT имеющие префикс RDP_DNAT.

add action=dst-nat chain=dstnat comment="..." dst-address=1.2.3.4 dst-port=12345 log=yes log-prefix=RDP_DNAT protocol=tcp src-address-list=\ !rdp_banlist to-addresses=192.168.200.181 to-ports=3389

Примерно так. То есть днатим все, кроме того, что есть в rdp_banlist.

В этом варианте есть плюс и минус.

Плюс в том, что подключения тут же прекратятся.

Минус в том, что больше этот ip не будет попадать в БД traflog и по истечении суток, когда пройдет таймаут хранения в блэклисте, он снова начнет гадить.

Вариант второй: добавить список rdp_banlist с восклицательным знаком в правило firewall цепочки forward, где мы разрешаем прохождение трафика на TCP 3389, аналогично тому, как это сделали в первом способе.

add action=accept chain=forward comment="..." dst-port=3389 log=yes log-prefix=ACCEPT_RDP protocol=tcp src-address-list=\ !rdp_banlist to-ports=3389

Примерно так. Разрешаем все, кроме того, что в банлисте.

Тут тоже плюс и минус.

В БД traflog будут продолжать сыпаться логи с префиксом RDP_DNAT, по которым мы определяем признак атаки. Плюс. В результате, когда закончится таймаут бана определенного хоста, продолжающего попытки брутфорса, он вновь будет добавлен в банлист после очередного запуска назначенного задания.

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

Старый и не очень надежный фокус, может легко забанить «хороших» клиентов и при этом пропустить «плохих», вежливо расчитавших таймаут stage1. В общем решение за вами, я выбрал оба 🙂 (на самом деле, в таком случае работает только первый), так как второй у меня был включен раньше и механика там была другая, основанная на последовательной записи в списки stage1, stage2, stage3, banlist… ну вы поняли.

Назначенное задание crontab

Осталось добавить назначенное задание в кронтаб:

root@monix:/root# echo '12 * * * * root /usr/share/traflog/scripts/rdp_brute.sh >/dev/null 2>&1' >> /etc/crontab

Такая запись будет запускать скрипт каждый час в 12 минут.

По обстоятельствам буду дополнять и исправлять ошибки. Надо признаться, я только сегодня закончил работу над этой механикой и с большой долей вероятности, что-то может пойти не так. Хочется пить спать спокойно в новогодние праздники, потому и тороплюсь закончить.
Вот пожалуй и все.

Всем спасибо за внимание и с наступающим Новым Годом!

Список литературы:

Документация по mysql
Документация по Mikrotik firewall
Спасибо Андрею Смирнову за статью про подключение по ключу dsa.

Теги
Показать больше

Похожие статьи

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть