Защита опубликованного RDP-сервера с помощью Mikrotik

Простой способ автоматически блокировать «брутфорсеров», пытающихся подобрать пароли к какому-либо из ваших опубликованных через Микротик сервисов.

Идея:

  • тем или иным образом отфильтровываем «новое подключение» злоумышленника. Обратите внимание! Если речь идет про 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-флага, и если оставить три уровня, то честный пользователь, забывший пароль может неожиданно для себя попасть в бан лист уже со второй попытки.
  • правила идут в обратном порядке. Если расположить их по-порядку, то проходя по цепочке firewall rules IP по очереди попадет во все временные списки и в итоговый банлист, а нам это не нужно. Мы хотим, чтобы именно каждая новая попытка подключения — заносила IP в список следующего уровня.
  • помониторьте работу правил и наполнение банлистов несколько дней. В правилах приведенных выше — есть включенный флаг логирования, вы будете видеть в логе Микротик все срабатывания.

Готово. Можно проверять.

5 Thoughts on “Защита опубликованного RDP-сервера с помощью Mikrotik

  1. Kirill on 2020-04-04 at 18:00 said:

    Большое спасибо! Настроил данное правило на всю подсеть предприятия, блэклист заполнился с космической скоростью )

  2. Дмитрий on 2020-10-28 at 16:18 said:

    Тут есть загвоздка: Если в течении времени нахождения адреса в списке 1-3 пользователь переподключится (н-р соединение прервалось или надо зайти под другим пользователем), он продолжит двигаться по спискам и, скорее всего, окажется в блок-листе
    Надо дорабатывать: удалять IP из листов при удачном соединении

    • acherepov on 2020-10-28 at 16:38 said:

      Абсолютно верно.
      но я не нашел как можно достоверно понять микротиком что «соединение установлено нормально».
      Может вы подскажете?
      Поэтому я пошел по второму пути: перенес блокировку брутфорса RDP-служб с роутера на сервер, который совершенно точно знает (и пишет в лог) что «была попытка ввести неправильный пароль с такого-то адреса».
      Чем можно воспользоваться, написать простой скрипт и повесить его на событие «появление записи с ID таким-то в логе таком-то»
      Вот тут описал https://dcub.ru/primitivnaya-zashhita-opublikovannogo-rdp-servera/

      П.С. А в версии сервера 2016 и старше — в одном и том же сообщении в логе указывается и IP злоумышленника, и используемый логин — вообще красиво можно сделать…

      • Дмитрий on 2020-10-29 at 23:15 said:

        Просто микротиком, без разбора каждой конкретной сессии — никак. А, учитывая протокол, который обсуждаем — совсем никак 🙂
        Только комплексно, используя данные самого сервера.

        У меня нет возможности/желания/необходимости обновлять имеющийся 2008 до 2012/2016, потому настроил не 3 а 10 «левелов».

        Но, теоретически, простой ограниченный «костыль» ( когда требуется несколько сессий с одного адреса или возможны частые реконнекты) делается следующийм образом: в логах терминального сервера ( на примере 2008) при логине появляется событие с кодом 4778, где в дополнительных сведениях указан IP клиента. Логон-скрипт берет этот IP, сверяет его со списком локальных и кладет в White-List на 60 минут. Бинго!

        • acherepov on 2020-11-18 at 09:52 said:

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

          Но все равно — больно громоздко получается.
          Хотя и реализуемо.

Добавить комментарий для Kirill Отменить ответ

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

Post Navigation

Яндекс.Метрика