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

Использование базы данных лога 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 нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

WebAssembly в продакшне и «минное поле» Smart TV: интервью с Андреем Нагих

Разработка приложений под Smart TV — тоже «нетипичный JavaScript», когда все слышали о чём-то, но немногие лично пробовали. Интерес к WebAssembly велик, но пока что нечасто встретишь людей, использующих эту технологию в рабочем проекте. TV, а в последние месяцы так ...

[Перевод] Ethereum планирует стать на 99% экономичней

Криптовалюта скоро сядет на энергетическую диету, чтобы конкурировать с более эффективными блокчейнами На фоне ажиотажа вокруг Биткоина его «младший брат» Ethereum отошел в тень. Но проект с рыночной капитализацией около 10 млрд долларов вряд ли можно считать незаметным. И объемы ...