Вопрос или проблема
Traefik идеально интегрируется с Docker-сервером в качестве обратного прокси, с настройкой через Docker-лейблы.
Вы можете определить промежуточные серверы (middlewares) для сервиса, которые затем валидируются по очереди и ограничивают доступ к сервису. Таким образом, если вы настроите промежуточные серверы, например IPAllowList
и BasicAuth
, они должны быть валидны по порядку.
Пример настройки лейблов для Docker-контейнера:
traefik.enable=true
traefik.http.routers.myapp.entryPoints=https
traefik.http.routers.myapp.rule=Host(`myapp.example.com`) && PathPrefix(`/`)
traefik.http.routers.myapp.middlewares=myapp-ipallow,myapp-auth
traefik.http.routers.myapp.service=myapp
traefik.http.routers.myapp.tls=true
traefik.http.routers.myapp.tls.certresolver=letsencrypt
traefik.http.services.myapp.loadbalancer.server.port=3000
traefik.http.middlewares.myapp-ipallow.ipallowlist.sourcerange="127.0.0.1/32, 192.168.0.0/24"
traefik.http.middlewares.myapp-auth.basicauth.users=example:$2y$05$KOCayy.mSsU.PmY7fzZSxuBohzWtnDJCAo02zUB/K7zrX70LG5pHi
Я ищу способ разрешить доступ из определённых сетей, требуя базовую аутентификацию только из всех остальных сетей.
Другими словами: разрешить доступ к сервису, если промежуточные серверы IPAllowList
(например, myapp-ipallow
) действительны, иначе если промежуточные серверы BasicAuth
(например, myapp-auth
) действительны.
Возможно ли настроить промежуточные серверы с помощью “или”?
Как эту конфигурацию можно реализовать, используя Traefik Proxy?
Ответ или решение
Traefik — это современный и гибкий инструмент для конфигурации обратного прокси, который часто используется в Docker-средах благодаря поддержке меток контейнеров для настройки маршрутизации и доступа. Один из интересных аспектов использования Traefik — это возможность управления доступом через middlewares, такие как IPAllowList и BasicAuth. Однако, согласно стандартной логике их применения, они последовательно проверяются, что означает, что все middlewares должны быть пройдены для получения доступа. В вашем случае требуется использование логики "или", где доступ предоставляется либо на основании IP-списка, либо аутентификации по паролю.
Теория
Для начала, давайте обсудим, как работает механизм middlewares в Traefik:
-
IPAllowList: Этот middleware используется для ограничения доступа на основании IP адресов. С помощью него можно определить список IP, которым будет разрешен доступ.
-
BasicAuth: Этот middleware требует от пользователей ввести имя пользователя и пароль для получения доступа к сервису.
По умолчанию, когда вы применяете несколько middlewares к маршрутизатору (router) в Traefik, они работают последовательно — то есть, чтобы доступ был разрешен, все middlewares должны успешно пройти проверку.
Пример
Рассмотрим ваш пример конфигурации:
traefik.enable=true
traefik.http.routers.myapp.entryPoints=https
traefik.http.routers.myapp.rule=Host(`myapp.example.com`) && PathPrefix(`/`)
traefik.http.routers.myapp.middlewares=myapp-ipallow,myapp-auth
traefik.http.routers.myapp.service=myapp
traefik.http.routers.myapp.tls=true
traefik.http.routers.myapp.tls.certresolver=letsencrypt
traefik.http.services.myapp.loadbalancer.server.port=3000
traefik.http.middlewares.myapp-ipallow.ipallowlist.sourcerange="127.0.0.1/32, 192.168.0.0/24"
traefik.http.middlewares.myapp-auth.basicauth.users=example:$2y$05$KOCayy.mSsU.PmY7fzZSxuBohzWtnDJCAo02zUB/K7zrX70LG5pHi
В этой конфигурации оба middlewares должны быть пройдены для того, чтобы получить доступ к сервису. Но задача заключается в том, чтобы обеспечить доступ к сервису, если выполняется хотя бы одно из условий — доступ из определенного IP-диапазона или успешное прохождение BasicAuth.
Применение
К сожалению, текущая версия Traefik (по состоянию на октябрь 2023 года) не поддерживает из коробки логическое "или" между middlewares. Однако есть несколько подходов, которые можно частично использовать для достижения подобного поведения.
-
Использование нескольких маршрутизаторов: Один из возможных способов решения проблемы — это создание нескольких разных маршрутизаторов для одного и того же сервиса — каждый со своими собственными наборами middlewares. В этом случае каждый маршрутизатор будет отвечать только за свою цепочку middlewares и будет действовать независимо.
Пример конфигурации:
traefik.http.routers.myapp-ip.rule=Host(`myapp.example.com`) && PathPrefix(`/`) traefik.http.routers.myapp-ip.middlewares=myapp-ipallow traefik.http.routers.myapp-ip.service=myapp traefik.http.routers.myapp-ip.tls=true traefik.http.routers.myapp-ip.tls.certresolver=letsencrypt traefik.http.routers.myapp-auth.rule=Host(`myapp.example.com`) && PathPrefix(`/`) traefik.http.routers.myapp-auth.middlewares=myapp-auth traefik.http.routers.myapp-auth.service=myapp traefik.http.routers.myapp-auth.tls=true traefik.http.routers.myapp-auth.tls.certresolver=letsencrypt
В этом случае, каждый маршрутизатор предоставляет доступ к тому же сервису, но через разные условия аутентификации.
-
Custom Applications/Middleware: Альтернативный подход предполагает разработку собственного middleware, который будет работать с использованием логики "или". Это может быть реализовано в виде небольшого прокси-сервера перед вашим приложением, который будет обрабатывать входящие запросы и выполнять нужную логику перед отправкой трафика далее.
-
Совместное использование с внешними инструментами: В случае если вам необходимо более гибкое решение, вы можете рассмотреть возможность использования Traefik совместно с внешними средствами (например, Nginx), где подобную логику можно реализовать более просто.
Заключение
Идеальной, встроенной поддержки для реализации "или" логики между middlewares в Traefik на данный момент нет. Однако, благодаря гибкости, которую предлагает Traefik, возможны различные подходы к решению такой задачи в зависимости от ваших потребностей. Выбор между использованием нескольких маршрутизаторов или внешних инструментов зависит от масштаба и специфики вашего проекта. Важно внимательно подходить к настройке безопасности, так как неправильное применение может привести к нежеланным уязвимостям.