Files
knowledge-base/decisions/2026-06-26-authentik-sso-deploy.md
dttb d39ddb989d authentik SSO/IdP на auth.dttb.ru (LXC 144): пилот OIDC Open WebUI+Gitea, обязательная 2FA
- LXC 144 Debian12/Docker, server+worker+postgres (2026.5.3, без Redis)
- NPM #41 auth.dttb.ru, LE cert id133, публичная A-запись Spaceweb
- OIDC: Open WebUI (chat) + Gitea (git, ROOT_URL→https)
- 2FA обязательна на IdP (TOTP/WebAuthn force-enroll)
- принцип «2FA через нужную дверь» (OIDC, не forward-auth)
- критичную инфру не трогали; остался ручной enrollment Олега

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 19:17:10 +03:00

8.8 KiB
Raw Blame History

date, type, tags
date type tags
2026-06-26 decision
dttb
sso
authentik
oidc
mfa
security

authentik — SSO/IdP для home lab (LXC 144)

Статус: платформа развёрнута и здорова, пилот OIDC на Open WebUI + Gitea работает (серверная часть). Остался один ручной шаг Олега — первый вход + enrollment 2FA (см. ниже). Домен: https://auth.dttb.ru · Контейнер: LXC 144 (10.0.0.144)

Зачем

Единый вход (SSO) + обязательная 2FA на сервисы home lab. Self-hosted IdP, без облака — в линию с уходом от big-tech project_deapple_migration.

Ключевое архитектурное решение: «2FA на всё, но через нужную дверь»

Олег хотел завести все сервисы за SSO с 2FA. Лобовой «всё за forward-auth» отвергнут — сломал бы не-браузерные клиенты (которых у нас много). Принято разделение:

Схема Для чего Почему
OIDC/SAML (вход в веб-морду через authentik+2FA, машинные пути живут штатно) сервисы с родной поддержкой SSO: Gitea, Nextcloud, Proxmox, Portainer, Open WebUI, Grafana, Home Assistant не ломает API, git push, WebDAV, мобилки
Forward-auth (outpost + advanced-config сниппет в NPM) голые дашборды без логина / на Basic Auth (german, KasmVNC) NPM не имеет родного auth-поля
Родной 2FA Proxmox (встроенный TOTP/WebAuthn), NPM не закрывать себе путь восстановления через IdP
Не за SSO вообще API (OmniRoute omni:20128/v1), webhooks (bot.dttb.ru), не-HTTP (RustDesk, IMAP/SMTP, Matrix federation), Vaultwarden (свой мастер-пароль+2FA) forward-auth их убьёт / антипаттерн

Почему forward-auth-везде плох именно у нас: Nextcloud (мобилка/WebDAV/rclone-bisync KB-синк), Gitea (git push), OmniRoute API (openclaw/german/swarmclaw/open-webui/code-server), bot webhooks, Mailcow IMAP/SMTP, RustDesk 21115-21119, Home Assistant/Matrix/Plex клиенты — всё это не проходит SSO-редирект.

Развёртывание (что сделано)

Контейнер LXC 144

  • Debian 12, unprivileged + nesting/keyctl, onboot=1
  • 2 vCPU / 4 GB / swap 2 GB / rootfs 20 GB на storage work (local-lvm забит 94%)
  • IP статика 10.0.0.144/24, gw 10.0.0.1, nameserver 1.1.1.1 (против FakeIP при pull с ghcr — урок 2026-06-22-open-webui-deploy)
  • root-пароль LXC: см. credentials
  • Docker 29.6 + compose (official get.docker.com)

Стек (официальный compose, /opt/authentik/)

  • ghcr.io/goauthentik/server:2026.5.3server + worker + postgresql:16-alpine
  • ⚠️ 2026.5.3 ушёл от Redis — теперь postgres-backed cache (django_postgres_cache). Compose БЕЗ redis. Проще.
  • AVX-граблю (как Mongo для UniFi 2026-06-15-unifi-controller-homelab) authentik не задевает — Python/PG/нет Mongo.
  • .env: PG_PASS, AUTHENTIK_SECRET_KEY (сгенерированы), AUTHENTIK_BOOTSTRAP_PASSWORD/_EMAIL, порты 9000/9443. Бэкап секретов — в самом .env контейнера.
  • Миграции БД при первом старте ~3 мин (health 503 в это время — норма, не паниковать).

Домен auth.dttb.ru

  • Публичная A-запись добавлена на Spaceweb: auth → 176.62.183.186 (нет wildcard — у каждого поддомена своя запись).
  • NPM proxy host id 4110.0.0.144:9000, LE cert id 133, Force SSL + HTTP/2 + WSS.
  • Локально/в NetBird *.dttb.ru = 10.0.0.195 (wildcard на роутере) — SSO работает и внутри.

2FA — обязательна на уровне IdP

Стейдж default-authentication-mfa-validation переведён not_configured_action: skip → configure, configuration_stages = [TOTP-setup, WebAuthn-setup]. Любой вход без устройства принуждает к установке TOTP или passkey. Действует на ВСЕ OIDC-логины (они идут через default-authentication-flow).

Пилот OIDC (работает серверно)

Сервис authentik app/slug client_id redirect_uri как подключён
Open WebUI (chat.dttb.ru, LXC 142) open-webui 1G7PLkPU… https://chat.dttb.ru/oauth/oidc/callback контейнер пересоздан с OAuth env, скрипт /root/recreate-owui.sh. Локальный логин СОХРАНЁН (ENABLE_LOGIN_FORM не трогали), OAUTH_MERGE_ACCOUNTS_BY_EMAIL=true
Gitea (git.dttb.ru, LXC 136) gitea AYl8jNZv… https://git.dttb.ru/user/oauth2/authentik/callback auth source «authentik» (id 1) через gitea admin auth add-oauth. ROOT_URL изменён http://10.0.0.189:3000/ → https://git.dttb.ru/ (иначе callback не совпадал). Бэкап app.ini.bak-preauthentik-20260626. git push/SSH не затронуты

Секреты client_secret — в credentials.

⚠️ Остался ручной шаг Олега (1 раз)

SSO-вход нельзя докрутить headless — нужен браузер Олега:

  1. Зайти на https://auth.dttb.ru, логин akadmin / пароль (см. credentials).
  2. Система сама предложит установить 2FA (TOTP — отсканировать QR в Google Authenticator/2FAS, или passkey). Установить.
  3. Проверить вход через SSO: на chat.dttb.ru кнопка «Continue with authentik», на git.dttb.ru «Sign in with authentik».
  4. (Опц.) создать личного пользователя oleg вместо akadmin, akadmin оставить как break-glass.

Плюсы / минусы

Плюсы: единый вход + 2FA на все совместимые сервисы; централизованное управление (можно выдавать семье/клиентам скоуп-доступ); forward-auth прикроет голые панели; self-hosted; журнал входов. Минусы/риски (и митигация):

  • SPOF/lockout: упал authentik → нет SSO-входа. → критичную инфру (Proxmox/NPM/Vaultwarden) НЕ гейтим, у сервисов сохраняем родной admin-логин как fallback.
  • Публичный IdP = поверхность атаки. → обязательная 2FA (включена), сильные пароли. Опц. позже: geo/fail2ban, ограничить admin LAN-only.
  • Лок единственного админа при кривом MFA-flow. → recovery через API-токен (минует flow) и ak shell (см. ниже).

Recovery / управление

  • API-токен (минует login-flow): claude-bootstrap — в credentials. curl https://auth.dttb.ru/api/v3/core/users/me/ -H "Authorization: Bearer <tok>".
  • Сбросить пароль akadmin: pct exec 144 -- bash -c "cd /opt/authentik && echo 'akadmin <newpass>' | docker compose exec -T server ak change_password akadmin" (или через ak shell).
  • Снять обязательную 2FA (если залочило): PATCH стейджа f3808685-… not_configured_action=skip через API-токен.
  • Логи: cd /opt/authentik && docker compose logs server|worker.
  • Обновление: бампить AUTHENTIK_TAG в /opt/authentik/.envdocker compose pull && up -d.

Spaceweb DNS — найден read-метод API

К ../projects/dttb/spaceweb-dns: метод чтения зоны = info (params {domain}), возвращает все записи с index/category. Существующие методы: editMain, editMx, editTxt, info. Добавление одной A-записи editMain {action:"add",name,type:"A",value,prefix:""} — безопасно (ломает зону только цикл).

Дальше (отдельными задачами, по согласованию)

Полный OIDC-роллаут: Proxmox (realm OpenID Connect), Nextcloud (app user_oidc/sociallogin), Portainer, Home Assistant, Grafana. Forward-auth demo на german.dttb.ru (Basic Auth → outpost). См. раздел «нужная дверь» выше.