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