Простой способ автоматически блокировать «брутфорсеров», пытающихся подобрать пароли к какому-либо из ваших опубликованных через Микротик сервисов.
Идея:
- тем или иным образом отфильтровываем «новое подключение» злоумышленника. Обратите внимание! Если речь идет про DST-NAT (т.е. некий внутренний сервер, входящий порт которого опубликован снаружи), то фильтрация будет в forward-chain.
- Заносим src-IP этого «нового подключения» в временный «список 1 уровня» с таймаутом скажем 30 минут
- Далее делаем еще несколько уровней, куда последовательно будем заносить Src-IP из предыдущего уровня. Таким образом, если за время жизни списка некто попытается несклько раз подключиться (типовая ситуация — брутфорс логинов-паролей), то он последовательно попадет в списки 1,2,3 и т.д. уровней
- Итоговое правило: из последнего списка занести Src-IP в постоянный бан-лист
Реализация (В качестве примера рассмотрим опубликованный RDP-сервер, TCP-3389, с внутренним IP=192.168.1.15. Служба опубликована снаружи на нестандартном порту TCP-25000, временные списки — 3 уровней, т.е. по сути дается три попытки на подключение, таймаут 30 мин на список):
- Первым добавляем правило, блокирующее форвард на внутренний сервер для всех из постоянного банлиста:
add action=drop chain=forward comment="Drop Bad-IP address (rdp brutforce)" dst-port=3389 in-interface=ether1-WAN protocol=tcp src-address-list=BAD-IP-auto
- Добавляем правило заносящее IP из списка 3 уровня в постоянный банлист
add action=add-src-to-address-list address-list=BAD-IP-auto address-list-timeout=none-static chain=forward dst-address=192.168.1.15 dst-port=3389 log=yes log-prefix=FW_BAN protocol=tcp src-address-list=rdp_brutforce_level3 tcp-flags=syn
- Добавляем правило заносящее IP из временного списка 2 уровня во временный список 3 уровня
add action=add-src-to-address-list address-list=rdp_brutforce_level3 address-list-timeout=30m chain=forward dst-address=192.168.1.15 dst-port=3389 log=yes log-prefix=FW_Lev3 protocol=tcp src-address-list=rdp_brutforce_level2 tcp-flags=syn
- Добавляем правило заносящее IP из временного списка 1 уровня во временный список 2 уровня
add action=add-src-to-address-list address-list=rdp_brutforce_level2 address-list-timeout=30m chain=forward dst-address=192.168.1.15 dst-port=3389 log=yes log-prefix=FW_Lev2 protocol=tcp src-address-list=rdp_brutforce_level1 tcp-flags=syn
- Добавляем правило заносящее IP во временный список 1 уровня
add action=add-src-to-address-list address-list=rdp_brutforce_level1 address-list-timeout=30m chain=forward dst-address=192.168.1.15 dst-port=3389 log=yes log-prefix=FW_Lev1 protocol=tcp tcp-flags=syn
ОБРАТИТЕ ВНИМАНИЕ!:
- В данном примере «новое подключение злоумышленника» мы отфильтровываем по параметрам
- chain, dst-address, dst-port и ключевой параметр
tcp-flags=syn
. т.е. все новые попытки установить TCP-соединение на эту службу будут попадать под фильтр. - Для других служб — параметры могут быть иными (конкретно речь про
tcp-flags=syn
) - обязательно протестируйте работу правил НЕ СО СВОЕЙ МАШИНЫ. Например в данном примере число уровней лучше повысить до 4 или еще больше уровней, т.к. как показал тест, при новом подключении с ранее не подключавшегося ноутбука стандартным MSTSC клиентом проходит аж три SYN-флага, и если оставить три уровня, то честный пользователь, забывший пароль может неожиданно для себя попасть в бан лист уже со второй попытки.
- chain, dst-address, dst-port и ключевой параметр
- правила идут в обратном порядке. Если расположить их по-порядку, то проходя по цепочке firewall rules IP по очереди попадет во все временные списки и в итоговый банлист, а нам это не нужно. Мы хотим, чтобы именно каждая новая попытка подключения — заносила IP в список следующего уровня.
- помониторьте работу правил и наполнение банлистов несколько дней. В правилах приведенных выше — есть включенный флаг логирования, вы будете видеть в логе Микротик все срабатывания.
Готово. Можно проверять.
Большое спасибо! Настроил данное правило на всю подсеть предприятия, блэклист заполнился с космической скоростью )
Тут есть загвоздка: Если в течении времени нахождения адреса в списке 1-3 пользователь переподключится (н-р соединение прервалось или надо зайти под другим пользователем), он продолжит двигаться по спискам и, скорее всего, окажется в блок-листе
Надо дорабатывать: удалять IP из листов при удачном соединении
Абсолютно верно.
но я не нашел как можно достоверно понять микротиком что «соединение установлено нормально».
Может вы подскажете?
Поэтому я пошел по второму пути: перенес блокировку брутфорса RDP-служб с роутера на сервер, который совершенно точно знает (и пишет в лог) что «была попытка ввести неправильный пароль с такого-то адреса».
Чем можно воспользоваться, написать простой скрипт и повесить его на событие «появление записи с ID таким-то в логе таком-то»
Вот тут описал https://dcub.ru/primitivnaya-zashhita-opublikovannogo-rdp-servera/
П.С. А в версии сервера 2016 и старше — в одном и том же сообщении в логе указывается и IP злоумышленника, и используемый логин — вообще красиво можно сделать…
Просто микротиком, без разбора каждой конкретной сессии — никак. А, учитывая протокол, который обсуждаем — совсем никак 🙂
Только комплексно, используя данные самого сервера.
У меня нет возможности/желания/необходимости обновлять имеющийся 2008 до 2012/2016, потому настроил не 3 а 10 «левелов».
Но, теоретически, простой ограниченный «костыль» ( когда требуется несколько сессий с одного адреса или возможны частые реконнекты) делается следующийм образом: в логах терминального сервера ( на примере 2008) при логине появляется событие с кодом 4778, где в дополнительных сведениях указан IP клиента. Логон-скрипт берет этот IP, сверяет его со списком локальных и кладет в White-List на 60 минут. Бинго!
Ну даже не знаю…
Событий при успешном логоне в логах я нашел несколько разных, где упоминается Source-IP.
У меня правда подопытный Server 2008R2, а не 2008.
Во-первых: мне кажется искать в Security log — не самая удачная идея, ID4778 — я вообще не нашел ни одного (наверное ошиблись? или это у меня 2008R2 и тут ID другие?). А вот ID4624 генерится аж дважды при входе, причем в одном случае IP -есть, а в другом — нет. Как на этот ID ориентироваться — непонятно.
Наверное в 2008R2 сервере я бы рекомендовал искать в логе Microsoft-Windows-TerminalServices-LocalSessionManager/Operational там событие с ID25 как раз и содержит все нужное
и второе: делать это логон скриптом я бы тоже не стал, т.к. он по сути выполняется из контекста пользователя, и вносит изменения в Mikrotik, а это значит что пользователь, при достаточном любопытстве сможет докопаться до скрипта и внести в Mikrotik неправильные изменения. Небезопасно.
Я бы делал это через Task Sheduler уже от имени админа и запускаемый скрипт лежал бы в недоступной пользователям области.
А срабатывание — по стандартному Attach Task to this Event, т.е. случилось событие — оно автоматом вызывает запуск скрипта.
Но все равно — больно громоздко получается.
Хотя и реализуемо.