# Traefik ForwardAuth: HTML-логин для внутренних сервисов ## 1. Контекст Текущая схема использует BasicAuth — браузерный нативный диалог, не кастомизируемый. ForwardAuth позволяет заменить его на HTML-страницу входа с сессиями. **Что меняется:** вместо `Middleware basicAuth` → `Middleware forwardAuth` + отдельный auth-pod. --- ## 2. Как работает ForwardAuth ``` Клиент → Traefik :10002 → ForwardAuth Middleware │ ▼ auth-сервис /auth │ ┌───────────┴───────────┐ │ 200 OK │ 401 → redirect на /login │ (сессия валидна) │ (HTML-страница логина) ▼ ▼ longhorn-frontend форма → POST /login │ проверка пароля │ Set-Cookie session │ redirect обратно ``` Traefik делает subrequest на `authResponseHeaders` — если auth-сервис вернул 200, пропускает запрос дальше. Если 401/302 — возвращает клиенту ответ auth-сервиса (redirect на страницу логина). --- ## 3. Варианты реализации ### 3.1. oauth2-proxy (рекомендуется) **Что это:** легковесный reverse-proxy с поддержкой htpasswd, GitHub, Google, OIDC. Для внутреннего использования подходит режим `--htpasswd-file` без внешнего провайдера. **Плюсы:** - Один pod, ~50MB RAM - Htpasswd-файл через Kubernetes Secret — никаких внешних зависимостей - HTML-форма из коробки, можно переопределить шаблоны - Cookie-сессии, configurable TTL **Минусы:** - Один экземпляр oauth2-proxy на весь Traefik (или по одному на сервис) - Нет 2FA **Схема деплоя:** ``` roles/oauth2-proxy/ tasks/main.yml — Kubernetes Deployment + Service tasks/secret.yml — инструкция по созданию htpasswd Secret вручную tasks/middleware.yml — ForwardAuth Middleware CRD inventory/prod/group_vars/oauth2proxy.yml — cookie_secret, upstream, htpasswd ref ``` **Ключевые параметры:** ```yaml # Helm values / env vars --provider=htpasswd --htpasswd-file=/etc/oauth2-proxy/htpasswd --cookie-secret=<32-byte-random> # генерируется вручную --cookie-secure=false # HTTP, без TLS --email-domain=* --upstream=static://200 # ForwardAuth: upstream не используется ``` **Middleware CRD:** ```yaml apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: forwardauth-oauth2proxy namespace: traefik spec: forwardAuth: address: http://oauth2-proxy.traefik.svc:4180/oauth2/auth trustForwardHeader: true authResponseHeaders: - X-Auth-Request-User - X-Auth-Request-Email ``` --- ### 3.2. Authelia **Что это:** полноценный self-hosted identity provider. HTML-логин, 2FA (TOTP, WebAuthn), LDAP, правила доступа по пользователям/группам. **Плюсы:** - Красивая HTML-форма с брендингом - 2FA из коробки - Гранулярный контроль: разные пользователи для разных сервисов **Минусы:** - Требует Redis (сессии) + хранилище пользователей (файл или LDAP) - ~150MB RAM минимум - Сложнее в настройке (YAML-конфиг, несколько секретов) **Оправдано если:** нужен 2FA или несколько пользователей с разными правами. --- ### 3.3. thomseddon/traefik-forward-auth **Что это:** минималистичный ForwardAuth-сервис только для Google/OIDC OAuth. Для htpasswd **не подходит** — требует внешний провайдер. --- ## 4. Рекомендация Для текущего стека (внутренняя сеть, один оператор, нет SSO) — **oauth2-proxy с htpasswd**. | Критерий | oauth2-proxy | Authelia | |---|---|---| | RAM | ~50MB | ~150MB | | Внешние зависимости | нет | Redis | | 2FA | нет | да | | Сложность настройки | низкая | средняя | | HTML-логин | да (кастомизируемый) | да (красивый) | --- ## 5. Интеграция с текущим port_map Схема остаётся прежней — меняется только тип Middleware: ```yaml # inventory/prod/group_vars/traefik.yml traefik_port_map: - name: longhorn-ui port: 10002 backend: namespace: longhorn-system service: longhorn-frontend port: 80 scheme: http auth: type: forwardauth # вместо basicauth middleware: forwardauth-oauth2proxy # имя Middleware ``` При `type: forwardauth` шаблон `ingressroute.yml.j2` подставляет ForwardAuth Middleware вместо BasicAuth. При `type: basicauth` — как сейчас. --- ## 6. Порядок развёртывания (если решим внедрить) 1. Добавить роль `oauth2-proxy` в `roles/` 2. Добавить `playbooks/setup_oauth2proxy.yml` 3. Создать Secret с htpasswd вручную: ```bash kubectl create secret generic oauth2proxy-htpasswd \ --from-literal=htpasswd="$(htpasswd -nb admin 'pass')" \ -n traefik ``` 4. Создать Secret с cookie_secret: ```bash kubectl create secret generic oauth2proxy-cookie \ --from-literal=cookie-secret="$(openssl rand -base64 32)" \ -n traefik ``` 5. Заменить `basicAuth` Middleware на `forwardAuth` в IngressRoute для нужных сервисов 6. Удалить старые BasicAuth Middleware и Secret `traefik-auth-longhorn`