Лаборатория: собираем TOTP + heartbeat вокруг MikroTik

Цикл «Не светим лишнего». Выпуск 15.

Теоретическая схема у нас уже есть. Теперь полезно собрать маленький стенд, который можно без жалости ломать. Не надо сразу подключать боевой WinBox, IPMI и камеры. Сначала докажем, что доступ правильно открывается и, что гораздо важнее, правильно закрывается.

Что понадобится

На границе ставим MikroTik с RouterOS 7. У него есть WAN и отдельная защищаемая сеть, например VLAN protected-lab.

В защищаемой сети размещаем три разных ресурса:

Снаружи доступен только HTTPS-портал. Его административная часть слушает внутренний management-интерфейс или дополнительно закрыта firewall. RouterOS API доступен лишь worker с фиксированного управленческого адреса.

Сам портал удобно разделить на компоненты:

Для первого запуска всё это можно поднять на одной Linux VM в контейнерах. Разделение здесь логическое: позже компоненты получится разнести, не переписывая модель доступа.

Профили лаборатории

Не создаём универсальный список trusted. Заводим три роли.

lab-web разрешает только HTTPS к тестовому веб-сервису.

lab-ssh разрешает только TCP/22 к одному Linux-хосту.

lab-support разрешает HTTPS, SSH и RDP к конкретным тестовым адресам, но не ко всей VLAN.

Каждый TOTP-токен связан с одной или несколькими ролями. Пользователь не вводит destination вручную. На MikroTik заранее лежат правила, которые ссылаются на эти address-list.

Жизненный цикл сессии

Пользователь открывает портал и вводит TOTP. Backend проверяет код, срок действия токена, лимит попыток и разрешённые роли. Затем создаёт сессию с абсолютным максимумом, например два часа.

Браузер открывает WebSocket. Пока он жив, Redis содержит активную ссылку на пару внешний IP + роль. Worker раз в несколько секунд вычисляет нужное состояние и добавляет на MikroTik динамическую запись с timeout 60–90 секунд.

При штатном завершении worker удаляет запись сразу. Если любой компонент пропал, MikroTik сам удалит её по timeout. Это и есть fail closed.

Что проверять по шагам

1. Нулевое состояние. Без TOTP все три ресурса недоступны. Проверяем не только браузером, но и nmap, SSH и RDP-клиентом. Публичный портал при этом доступен.

2. Разные роли. Токен lab-web не должен открыть SSH. lab-ssh не должен дать RDP. Проверяем реальные правила, а не только подпись на странице.

3. Истечение времени. Не закрываем вкладку и ждём абсолютный максимум. Сессия обязана завершиться, даже если heartbeat продолжает идти.

4. Закрытие вкладки. При штатном WebSocket close доступ снимается быстро. Затем повторяем жёстко: убиваем браузер, отключаем сеть, усыпляем ноутбук. В этих случаях ждём окончания короткого lease.

5. Два пользователя за одним NAT. Открываем две сессии с одного публичного IP. Закрываем первую. Доступ второй роли обязан сохраниться. Закрываем последнюю — соответствующая запись исчезает.

6. Одинаковая роль за одним NAT. Две сессии требуют lab-ssh. После закрытия одной счётчик остаётся равным единице, и SSH не пропадает у второй.

7. Уже установленный SSH. Открываем соединение, затем отзываем сессию. Если терминал продолжает работать, значит порядок established,related, FastTrack или очистка connection tracking настроены неправильно.

8. Падение портала. Останавливаем backend и Redis. Новые доступы не выдаются, существующие исчезают после timeout. Никаких постоянных записей на MikroTik остаться не должно.

9. Потеря RouterOS API. Worker должен показать ошибку и не считать сессию успешно применённой. Старые leases естественно истекают.

10. Перезапуск worker. После запуска он восстанавливает правильное состояние из активных сессий, а не доверяет случайно оставшимся firewall-записям.

11. Смена внешнего IP. Переключаем сеть или внешний VPN. Старый адрес закрывается по lease. Новый не получает права автоматически без повторного подтверждения.

12. Рассинхронизация времени. Уводим часы портала и убеждаемся, что мониторинг NTP ловит проблему. TOTP очень не любит творческое отношение ко времени.

Плюсы такого стенда

Минусы

Где можно больно ошибиться

Тестировать только успешный вход. Самые важные сценарии — падение, отзыв и рассинхронизация.

Использовать боевые TOTP-секреты. Лаборатория должна иметь отдельные токены, ключи API, адреса и сертификаты.

Дать worker полный RouterOS admin. Даже в стенде стоит сразу строить отдельную учётку и management-доступ. Иначе опасная привычка доедет до production.

Считать состояние Redis единственной истиной. На точке применения всегда есть собственный короткий timeout. Потеряли оперативную базу — доступ закрывается.

Не собирать журнал. Для каждой записи нужны ID сессии, токен, роль, внешний IP, время создания, продления и причина закрытия.

Забыть IPv6. Если тестовый ресурс имеет глобальный IPv6 в обход MikroTik-политики, идеальный IPv4 heartbeat ничего не защищает.

Что получится в финале

После этих проверок у нас будет не просто страница с шестью цифрами, а понятный механизм: заранее проверенные группы ресурсов, временные роли, короткие firewall leases, живые браузерные сессии и гарантированный fail closed.

Дальше уже можно делать второй, практический цикл: конкретная схема БД, API портала, конфигурация RouterOS, Docker Compose и автоматические тесты. Но это будет отдельная инженерная работа, а не ещё одна статья в духе «добавьте правило accept и всё готово».

Ранее в цикле

Документация и источники

#network