Российские технологии и цифровая экономика
ПоискRSS

Kalitka перед reverse proxy: дополнительная защита grafana, n8n и админ-панелей

5 минут чтения

Зачем я поставил "калитку" перед reverse proxy и почему обычного логина оказалось недостаточно

У меня есть Grafana, n8n, Dockge, несколько административных панелей и staging-сайтов. Почти у каждого сервиса предусмотрена собственная авторизация: где-то используется пароль, где-то MFA, а где-то полноценная учётная запись. На первый взгляд этого вполне достаточно. Однако оставалась неприятная деталь: формы входа и сами приложения всё равно были доступны из интернета.

Даже если сервис надёжно защищён паролем, его можно обнаружить при сканировании, определить по заголовкам и особенностям поведения, проверить на наличие известных уязвимостей и атаковать через endpoint авторизации. Поэтому мне захотелось добавить перед reverse proxy ещё один, максимально простой рубеж.

Так появилась идея Kalitka - небольшой "предбанник" перед внутренними веб-сервисами. Подробное описание архитектуры и практических нюансов можно найти в материале о защите сервисов с помощью дополнительной калитки перед reverse proxy.

Что делает Kalitka

Kalitka не заменяет Identity Provider, не становится WAF и не отменяет встроенную авторизацию приложений. Это только предварительный фильтр. Его задача - не пустить посетителя к настоящему сервису, пока владелец инфраструктуры явно не подтвердит доступ.

Схема выглядит так: reverse proxy, например Traefik, получает HTTP-запрос и через механизм forwardAuth обращается к Kalitka. Если сессия уже разрешена, сервис возвращает HTTP 200, после чего Traefik передаёт запрос в Grafana, n8n или другую систему. Если разрешения нет, пользователь перенаправляется на специальную страницу.

Там он может указать имя, кратко описать цель обращения или просто нажать кнопку запроса доступа. После этого запрос получает статус ожидания, а администратор получает уведомление в Telegram. В сообщении отображаются основные сведения о посетителе, а рядом находятся кнопки подтверждения и отклонения.

После одобрения браузер получает подписанную cookie сессии и повторяет запрос. Только на этом этапе пользователь видит стандартную форму входа Grafana или другого приложения. Поэтому разрешение в Kalitka и авторизация внутри сервиса остаются двумя независимыми уровнями контроля.

Почему одного VPN оказалось недостаточно

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

Представим, что staging-систему требуется показать внешнему разработчику или заказчику. Вариант с VPN предполагает установку клиента, передачу конфигурации, импорт профиля, включение туннеля и иногда отдельные инструкции для компьютера и смартфона. Для регулярной работы это приемлемо, но для разового доступа получается избыточно.

Kalitka решает задачу проще: пользователь открывает обычный URL, отправляет запрос, а владелец подтверждает его из Telegram. Никаких конфигурационных файлов и специальных клиентов не требуется. При этом внутренний сервис продолжает использовать собственную учётную запись и не превращается в публичный ресурс.

Почему IP-allowlist не стал основным механизмом

Белый список IP выглядит ещё проще, но быстро сталкивается с реальностью: мобильные сети используют меняющиеся адреса, домашние подключения могут работать за CGNAT, а гостиничный или офисный Wi‑Fi редко предоставляет стабильный внешний IP.

Тем не менее IP-фильтрация остаётся полезной. Известные адреса можно автоматически пропускать, подозрительные - блокировать, а неизвестные отправлять на ручное подтверждение. Но IP нельзя считать полноценной идентичностью. Незнакомый адрес не обязательно принадлежит злоумышленнику - иногда это просто человек, который оказался в другой сети.

Именно поэтому безопасность reverse proxy лучше строить не на одном признаке, а на нескольких слоях: сетевых ограничениях, ручном подтверждении, сроке жизни сессии и встроенной авторизации приложения.

Почему не Authentik и не Authelia

Authentik, Authelia, Cloudflare Access и аналогичные продукты решают более масштабную задачу - централизованное управление идентичностями и политиками доступа. Это мощные инструменты, но для нескольких личных сервисов их внедрение может потребовать значительной настройки и сопровождения.

Мне не требовалась новая система учётных записей. Я хотел лишь отвечать на один вопрос: разрешить ли конкретному запросу добраться до приложения. Всё остальное - логины, роли, MFA и права пользователей - уже должны оставаться ответственностью самого сервиса.

В этом смысле аутентификация reverse proxy здесь не подменяет авторизацию, а добавляет предварительную проверку. Такой подход особенно удобен для защиты внутренних сервисов, которые нельзя полностью закрыть, но и выставлять без дополнительного фильтра тоже не хочется.

Важные технические нюансы

При настройке forwardAuth нужно заранее определить, какие данные получает Kalitka. В частности, важно корректно передавать исходный Host, путь запроса и IP клиента. Если reverse proxy находится за CDN или дополнительным балансировщиком, нельзя бездумно доверять заголовку `X-Forwarded-For`: его необходимо принимать только от известных промежуточных узлов.

Отдельный вопрос - поведение при сбое самой Kalitka. В режиме fail-open запросы могут пройти к внутреннему сервису, если проверяющий компонент недоступен. Это повышает доступность, но ухудшает защиту. Fail-closed, наоборот, блокирует обращения при любой ошибке, однако временная неисправность "калитки" может сделать сервис недоступным даже для владельца.

Для административных панелей обычно разумнее выбирать fail-closed. Исключение можно сделать для менее критичных приложений, если приоритетом является непрерывная работа.

Нужно внимательно проектировать и cookie. Если сессия действует на общий домен, она потенциально может использоваться сразу для нескольких поддоменов. Host-only cookie безопаснее с точки зрения изоляции, но для этого нередко приходится учитывать ограничения браузера, доменную структуру и особенности reverse proxy. Слишком широкая область действия сессии способна превратить удобство в дополнительный риск.

Telegram как панель управления

Telegram в этой схеме выступает не как средство входа пользователя, а как канал управления запросами. Администратор получает уведомление и принимает решение в привычном интерфейсе. Это удобно для временных разрешений, ручного аудита и экстренного отключения доступа.

Полезна и команда вроде `/mute`, которая позволяет временно отключить уведомления. Она не должна отключать саму защиту: запросы продолжают обрабатываться по правилам, но администратор временно не получает шум от повторяющихся событий.

При этом Kalitka не стоит перегружать функциями WAF. Ей не нужно анализировать каждую сигнатуру атаки, фильтровать SQL-инъекции или заменять специализированный сетевой экран. Чем уже зона ответственности компонента, тем проще его проверять, обновлять и восстанавливать.

Дополнительные сложности: polling и SPA

На практике проблемы могут возникнуть не только на этапе первого открытия страницы. Некоторые приложения регулярно выполняют polling-запросы, используют WebSocket или отправляют фоновые обращения к API. Если разрешение применяется только к основному документу, часть таких запросов может блокироваться.

Одностраничные приложения тоже способны удивить: после редиректа они иногда теряют исходный маршрут, повторяют запросы с другим набором заголовков или требуют корректной обработки preflight-запросов CORS. Поэтому тестировать нужно не только загрузку главной страницы, но и навигацию, обновление данных, выход из системы, открытие новых вкладок и работу API.

В итоге reverse proxy настройка с предварительным согласованием доступа стала для меня компромиссом между удобством и безопасностью. VPN остаётся отличным инструментом для постоянного доступа, IP-ограничения помогают снизить количество лишних запросов, а полноценные системы единого входа подходят для более крупных инфраструктур. Но для небольшой домашней или рабочей среды простая "калитка" закрывает конкретную проблему без чрезмерной сложности.

Главная идея здесь не в том, чтобы заменить пароли, MFA или права доступа. Она в том, чтобы настоящий сервис вообще не показывался каждому случайному сканеру. Сначала посетитель должен постучать, затем владелец решает, открывать ли дверь, а уже после этого приложение выполняет собственную проверку пользователя. Именно такая единая авторизация для веб-сервисов на предварительном уровне делает доступ управляемым, не ломая существующую архитектуру.

Прокрутить вверх