Authentik — centralny SSO dla całego homelaba na Proxmox LXC

Authentik — centralny SSO dla całego homelaba na Proxmox LXC

Authentik — centralny SSO dla całego homelaba na Proxmox LXC

Dlaczego Authentik?

Każda self-hosted aplikacja ma własne logowanie — Outline, NocoDB, Nextcloud, Portainer, Grafana. Zarządzanie dziesiątkami kont i haseł to koszmar, szczególnie gdy chcesz to ogarnąć dla szkoły z kilkudziesięcioma użytkownikami.

Authentik rozwiązuje ten problem — to self-hosted Identity Provider (IdP) który centralnie zarządza tożsamością użytkowników. Logujesz się raz i masz dostęp do wszystkiego.

Co zyskujesz:
- ✅ SSO (Single Sign-On) — jeden login dla wszystkich aplikacji
- ✅ MFA (TOTP, WebAuthn/passkey) ustawiane raz, działa wszędzie
- ✅ Centralne zarządzanie użytkownikami i grupami
- ✅ Pełne logi każdego logowania
- ✅ Polityki dostępu — np. Proxmox tylko z sieci lokalnej + MFA
- ✅ RADIUS — logowanie do WiFi tym samym kontem
- ✅ LDAP — dla aplikacji które nie obsługują OIDC (FreePBX, Canvas LMS)
- ✅ Proxy Provider — dodaje ekran logowania przed dowolną aplikacją bez SSO

Obsługiwane protokoły:
- OAuth2 / OpenID Connect (OIDC) — większość nowoczesnych aplikacji
- SAML — systemy edukacyjne, korporacyjne
- LDAP — starsze systemy
- RADIUS — VPN, WiFi (WPA2-Enterprise)


Architektura i środowisko

Proxmox
└── LXC: authentik (IP_LXC, VLAN server)
    └── Docker Compose
        ├── goauthentik/server:2026.2.1  → port 9000, 9443
        ├── goauthentik/worker:2026.2.1
        ├── postgres:16-alpine
        └── redis/redis

Dostęp przez Nginx Proxy Manager:
- TWOJA_DOMENA_AUTHENTIK → port 9000


Wymagania

LXC Proxmox:
- OS: Debian 13 (Trixie)
- CPU: 2 cores
- RAM: 3 GB (minimum 2 GB — warto dać zapas)
- Dysk: 15 GB
- VLAN: server/200
- Nesting: włączone — obowiązkowe dla Dockera w LXC

Wersje oprogramowania:
- Docker: 29.3.1
- Docker Compose: v5.1.1
- Authentik: 2026.2.1


Instalacja Dockera

apt update && apt upgrade -y
apt install -y ca-certificates curl gnupg

install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null

apt update && apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Instalacja Authentik

mkdir -p /opt/authentik && cd /opt/authentik

# Pobranie oficjalnego docker-compose
wget https://goauthentik.io/docker-compose.yml

# Generowanie kluczy — zapisz te wartości!
echo "PG_PASS=$(openssl rand -base64 36 | tr -d '\n')" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d '\n')" >> .env

# Sprawdź co zostało wygenerowane
cat .env

Uruchomienie:

docker compose pull
docker compose up -d

Sprawdź status — wszystkie trzy kontenery muszą być healthy:

docker compose ps
NAME                     IMAGE                                  STATUS
authentik-postgresql-1   postgres:16-alpine                     Up (healthy)
authentik-server-1       goauthentik/server:2026.2.1            Up (healthy)
authentik-worker-1       goauthentik/server:2026.2.1            Up (healthy)

Konfiguracja NPM i AdGuard

Wpis w NPM:
| Pole | Wartość |
|------|---------|
| Domain | TWOJA_DOMENA_AUTHENTIK |
| Scheme | http |
| Forward Hostname | IP_LXC |
| Forward Port | 9000 |
| Websockets Support | ✅ |
| SSL | Let's Encrypt, Force SSL ✅ |

Wpis w AdGuard Home → DNS Rewrites:

TWOJA_DOMENA_AUTHENTIK → <IP_NPM>

Pierwsze uruchomienie — initial setup

Wejdź na:

http://<IP_LXC>:9000/if/flow/initial-setup/

Ustaw hasło dla użytkownika akadmin. To jest konto superadmina — użyj silnego hasła i włącz MFA.


Konfiguracja domeny w Markach

Authentik musi znać swoją domenę — bez tego uwierzytelnianie nie działa.

Wejdź do Admin Interface → System → Marki → edytuj authentik-default

Zmień pole Domena na:

TWOJA_DOMENA_AUTHENTIK

Zapisz i zrestartuj:

docker compose restart server worker

Auto-start po restarcie serwera

Bez systemd service Authentik nie wstaje sam po restarcie LXC. Utwórz plik:

nano /etc/systemd/system/authentik.service
[Unit]
Description=Authentik SSO
After=docker.service
Requires=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/authentik
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=180

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable authentik.service

TimeoutStartSec=180 — ważne, opisuję dlaczego niżej w sekcji troubleshooting.


Watchtower — automatyczne aktualizacje

Watchtower w osobnym pliku compose:

nano /opt/authentik/docker-compose.watchtower.yml
services:
  watchtower:
    image: containrrr/watchtower
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - WATCHTOWER_CLEANUP=true
      - WATCHTOWER_SCHEDULE=0 0 3 * * *
    restart: unless-stopped
docker compose -f docker-compose.watchtower.yml up -d

Dodawanie aplikacji — przykład: Outline

Dla każdej aplikacji którą chcesz podpiąć do SSO tworzysz Provider i Aplikację.

Krok 1: Utwórz Provider

Admin Interface → Aplikacje → Dostawcy → Utwórz → OAuth2/OpenID Provider

Pole Wartość
Provider Name Provider for outline
Przepływ autoryzacji default-provider-authorization-explicit-consent
Client type Poufny
Redirect URI https://TWOJA_DOMENA_OUTLINE/auth/oidc.callback (tryb: Strict)
Klucz podpisujący authentik Self-signed Certificate

Zapisz automatycznie wygenerowane Client ID i Client Secret.

Krok 2: Utwórz Aplikację

Admin Interface → Aplikacje → Aplikacje → Utwórz

Pole Wartość
Name outline
Ślimak outline
URL uruchomienia https://TWOJA_DOMENA_OUTLINE
Dostawca Provider for outline

Krok 3: Konfiguracja po stronie aplikacji

W .env Outline dodaj:

OIDC_CLIENT_ID=<client_id>
OIDC_CLIENT_SECRET=<client_secret>
OIDC_AUTH_URI=https://TWOJA_DOMENA_AUTHENTIK/application/o/authorize/
OIDC_TOKEN_URI=https://TWOJA_DOMENA_AUTHENTIK/application/o/token/
OIDC_USERINFO_URI=https://TWOJA_DOMENA_AUTHENTIK/application/o/userinfo/
OIDC_USERNAME_CLAIM=email
OIDC_DISPLAY_NAME=Authentik
OIDC_SCOPES=openid profile email

Napotkane problemy i rozwiązania

Problem 1: "domena authentik nie jest skonfigurowana"

Ostrzeżenie w Placówkach (Outposts):

Ostrzeżenie: domena authentik nie jest skonfigurowana, uwierzytelnianie nie będzie działać.

Rozwiązanie: Admin Interface → System → Marki → edytuj authentik-default → ustaw domenę TWOJA_DOMENA_AUTHENTIK.

Problem 2: Authentik zwraca 404 dla authorize endpoint

Aplikacja wysyłała zapytanie na URL z nazwą aplikacji w ścieżce:

/application/o/outline/authorize/  ← 404!

Poprawny endpoint (bez nazwy aplikacji):

/application/o/authorize/  ← działa ✅

Zawsze weryfikuj poprawne URL-e przez endpoint OpenID Configuration:

https://TWOJA_DOMENA_AUTHENTIK/application/o/<slug>/.well-known/openid-configuration

Znajdziesz tam dokładne URL-e dla authorization_endpoint, token_endpoint i userinfo_endpoint.

Problem 3: Zmienne środowiskowe nie są przeładowywane po restart

docker compose restart nie przeładowuje zmiennych z .env. Po każdej zmianie w .env używaj:

docker compose down && docker compose up -d

Problem 4: Authentik nie wstaje po restarcie — systemd timeout

Po aktualizacji przez Watchtower (nocna, 3:00) następny restart LXC pokazał pusty docker compose ps — server i worker nie działały.

Przyczyna: Watchtower zaktualizował obrazy Postgresa i Authentika. Po restarcie Postgres potrzebował więcej czasu na inicjalizację z nowym obrazem. Domyślny TimeoutStartSec=90 w systemd powodował, że docker compose up -d był zabijany zanim Postgres zdążył odpowiedzieć jako healthy, a server/worker nawet nie próbowały startować.

Objawy:

systemctl status authentik.service
# → State: failed
# → ExecStart: ... code=killed, signal=TERM

docker compose ps
# postgres → Up (healthy)
# server   → brak
# worker   → brak

Rozwiązanie doraźne:

cd /opt/authentik
docker compose down && docker compose up -d

Rozwiązanie trwałe — w pliku authentik.service ustaw wyższy timeout:

TimeoutStartSec=180
systemctl daemon-reload
systemctl restart authentik.service

Timeout 180 sekund daje Postgresowi wystarczający czas nawet po aktualizacji obrazu.

Problem 5: Zduplikowane zmienne w .env aplikacji

Domyślne pliki .env.sample często zawierają zakomentowane zmienne OIDC. Jeśli dodasz swoje na końcu pliku, aplikacja może wczytać puste zakomentowane wartości zamiast twoich.

Rozwiązanie: usuń zakomentowane duplikaty (przykład dla Outline):

sed -i '/#OIDC_/d' /opt/outline/.env

Planowane integracje

Authentik będzie centralnym punktem uwierzytelniania dla całego homelaba i szkoły:

Jeden login w Authentik:
├── WiFi szkolne (RADIUS / WPA2-Enterprise)
├── Outline — wiki, notatki (OIDC) ✅
├── NocoDB — bazy danych (OIDC) ⏳
├── Nextcloud — pliki (OIDC) ⏳
├── Canvas LMS — e-learning (OIDC/SAML) ⏳
├── Portainer — zarządzanie Docker (OIDC) ⏳
├── Proxmox — hypervisor (OIDC) ⏳
├── FreePBX — VoIP (LDAP) ⏳
└── Poczta szkolna (LDAP) ⏳

Docelowo nauczyciel/uczeń ma jedno konto → dostęp do wszystkich szkolnych systemów. Nowy użytkownik → tworzysz jedno konto. Koniec roku → dezaktywujesz konta → zero dostępu do niczego.


Co działa

  • ✅ Authentik dostępny przez https://TWOJA_DOMENA_AUTHENTIK
  • ✅ SSO dla Outline — logowanie przez Authentik działa
  • ✅ Domena skonfigurowana w Markach
  • ✅ Watchtower — automatyczne aktualizacje co noc o 3:00
  • ✅ SSL przez NPM

Co zostało do zrobienia

  • ⏳ MFA (TOTP) dla konta akadmin
  • ⏳ SSO dla NocoDB
  • ⏳ SSO dla Nextcloud
  • ⏳ RADIUS dla WiFi MikroTik
  • ⏳ Grupy użytkowników i polityki dostępu
  • ⏳ SCIM provisioning dla Canvas LMS

Przydatne komendy

# Status kontenerów
docker compose ps

# Logi serwera
docker compose logs server --tail=30

# Logi workera
docker compose logs worker --tail=20

# Pełny restart
docker compose down && docker compose up -d

# Aktualizacja obrazów
docker compose pull && docker compose up -d