- Dies ist ein Bereitstellungsverfahren, bei dem Keycloak auf einer einzelnen Linux-VM isoliert mit rootless Docker läuft und das System-nginx die TLS-Terminierung sowie den Reverse Proxy übernimmt
- Voraussetzungen sind SSH-Zugriff, eine Domain oder Subdomain für Keycloak, ein
A-Record, ein passwortloser Benutzer keycloak, das Home-Verzeichnis /srv/keycloak und eine rootless-Docker-Installation
docker-compose.yml verwendet postgres:16 und quay.io/keycloak/keycloak:25.0.1; Keycloak bindet nur an 127.0.0.1:8080 und verwaltet Passwörter sowie KC_HOSTNAME in .env
- nginx leitet HTTP-Anfragen für
your.tld.com auf HTTPS um und gibt sie per proxy_pass weiter; nach der Zertifikatsausstellung mit Certbot wird KC_PROXY_HEADERS: xforwarded aktiviert
- Wenn ein benutzerdefiniertes Theme oder der Start mit
--optimized erforderlich ist, kann ein eigenes Image mit einem Multi-Stage-Dockerfile erstellt werden; im Betrieb lassen sich zusätzlich die JGroups-Puffergröße und die Quarkus-Transaktionswiederherstellung anpassen
Bereitstellungsstruktur und Voraussetzungen
- Keycloak ist eine Open-Source-IAM-Option, wenn es schwierig ist, Benutzerverwaltung und SSO direkt in einer Webanwendung selbst zu implementieren
- Es ist mit wichtigen SSO-Protokollen wie
OpenID Connect (OIDC), OAuth 2.0 und SAML interoperabel
- Die Konfiguration wurde auf Basis von Keycloak
23.0.6 geschrieben und bis 25.0.5 getestet
- Die Gesamtarchitektur nutzt nginx als zentralen Reverse Proxy und leitet Traffic pro Dienst an localhost innerhalb separater rootless-Docker-Namespaces weiter
- Web-Traffic kommt auf
0.0.0.0:80 und 0.0.0.0:443 an, und nginx leitet ihn an Keycloak auf 127.0.0.1:8080 weiter
- Ziel ist eine kosteneffiziente Konfiguration, die Dienstumgebungen trennt und gleichzeitig die Ressourcen eines einzelnen Hosts gemeinsam nutzt
Vorbereitungen
- Als Grundumgebung werden eine Linux-VM, SSH-Fernzugriff sowie eine Domain oder Subdomain für den Keycloak-Dienst benötigt
- Für die Domain wird ein
A-Record benötigt; optional kann ein AAAA-Record hinzugefügt werden
- Für die rootless-Docker-Grundkonfiguration wird dem Verfahren in einem separaten Mastodon-Beitrag gefolgt
- Einen neuen non-root-Benutzer
keycloak ohne Passwort anlegen
- Das Home-Verzeichnis auf
/srv/keycloak setzen
- In
/etc/subuid und /etc/subgid einen Bereich für den Benutzer keycloak hinzufügen
- rootless Docker mit
dockerd-rootless-setuptool.sh installieren
- Den automatischen Dienststart für den Benutzer
keycloak konfigurieren
Keycloak mit Docker Compose starten
- Um in den neu angelegten Benutzer
keycloak zu wechseln, wird machinectl shell keycloak@ verwendet
- Die Methode
sudo -u keycloak -H bash wird vermieden, da dabei die Umgebungsvariable XDG_RUNTIME_DIR nicht vorbereitet ist
- Zuerst werden Verzeichnisse für persistente Daten und Docker-Dateien erstellt
- Der PostgreSQL-Datenpfad ist
/srv/keycloak/data/postgres16
- Die Docker-Dateien liegen unter
~/docker
docker-compose.yml verwendet direkt das offizielle Keycloak-Image und PostgreSQL
- Das PostgreSQL-Image ist
postgres:16
- Das Keycloak-Image ist
quay.io/keycloak/keycloak:25.0.1
- Für Produktionsumgebungen wird empfohlen, statt
:latest einen konkreten Image-Tag zu verwenden
- Die wichtigsten Einstellungen des Keycloak-Containers sind wie folgt
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://postgres_db/keycloak
KC_HOSTNAME: ${KC_HOSTNAME:-your.tld.com}
KC_HTTP_ENABLED: true
HTTP_ADDRESS_FORWARDING: true
KEYCLOAK_ADMIN: admin
- Der Port wird mit
'127.0.0.1:8080:8080' nur an localhost gebunden
- In
.env stehen sensible oder umgebungsspezifische Werte
POSTGRES_PASSWORD
KEYCLOAK_ADMIN_PASSWORD
KC_HOSTNAME
- Die Syntax
${KC_HOSTNAME:-your.tld.com} verwendet den Wert aus .env, wenn dort KC_HOSTNAME gesetzt ist; andernfalls wird your.tld.com als Standardwert verwendet
/srv/keycloak/data/postgres16 enthält die persistenten Daten von PostgreSQL und sollte daher regelmäßig gesichert werden
- Für eine vollständige Initialisierung kann dieses PostgreSQL-Verzeichnis gelöscht und neu erstellt werden; beim nächsten Start wird es erneut angelegt
- Wenn
~/docker als Git-Repository verwaltet wird, kann .env in .gitignore aufgenommen und nur docker-compose.yml committet werden
Lokaler Test
- Den Docker-Compose-Stack starten und die Logs prüfen
docker compose up -d && docker compose logs --follow
- Um auf den lokalen Keycloak-Port der VM zuzugreifen, wird ein umgekehrter SSH-Tunnel eingerichtet
ssh you@111.11.11.11 -L :8080:127.0.0.1:8080 -p 22 -N -v
- Im Browser
127.0.0.1:8080 öffnen und den Keycloak-Willkommensbildschirm prüfen
nginx-Reverse-Proxy und TLS
- Nach dem Abmelden vom Benutzer
keycloak wird die System-nginx-Konfiguration vorgenommen
your.tld.com durch die echte Domain ersetzen und beim Domain-Registrar einen A-Record hinzufügen, damit DNS-Anfragen an die IP der VM gehen
- Die nginx-Site-Konfigurationsdatei erstellen und aktivieren
nano /etc/nginx/sites-available/your.tld.com.conf
ln -s /etc/nginx/sites-available/your.tld.com.conf /etc/nginx/sites-enabled/
- Die nginx-Konfiguration leitet HTTP-Anfragen auf HTTPS um und proxyt im HTTPS-Serverblock an Keycloak
proxy_set_header Host $host
proxy_set_header X-Real-IP $remote_addr
proxy_set_header X-Forwarded-For $remote_addr
proxy_set_header X-Forwarded-Proto $scheme
proxy_pass http://127.0.0.1:8080
- Für die SSL-Konfiguration wird empfohlen, mit dem Mozilla SSL configurator for nginx passende Standardwerte für die verwendete nginx-Version zu erzeugen
- Nach dem Test der Konfiguration nginx neu laden
nginx -t
systemctl reload nginx
- Wenn mit Certbot ein Zertifikat ausgestellt wird, werden die erforderlichen Zeilen in
your.tld.com.conf automatisch aktualisiert
certbot --nginx -d your.tld.com
- Danach
ssl_trusted_certificate /etc/letsencrypt/live/your.tld.com/chain.pem; aktivieren und nginx erneut neu laden
- Anschließend
KC_PROXY_HEADERS: xforwarded in docker-compose.yml aktivieren, damit der Betrieb hinter nginx korrekt funktioniert, und den Docker-Stack neu starten
docker compose down && docker compose up -d && docker compose logs --follow
Debugging-Pfade
- Nach der Konfiguration
your.tld.com aufrufen und die Anmeldung des Benutzers admin mit dem Passwort aus .env prüfen
- Die erste Prüfstation sind die Docker-Compose-Logs
docker compose logs --follow
- nginx-Zugriffs- und Fehler-Logs lassen sich über folgende Dateien verfolgen
tail -f /var/log/nginx/your.tld.com-access.log
tail -f /var/log/nginx/your.tld.com-error.log
- Wenn die Keycloak-Datenbank direkt geprüft werden muss, zum Benutzer
keycloak wechseln und psql im PostgreSQL-Container ausführen
machinectl shell keycloak@
cd ~/docker
docker compose exec postgres_db /bin/bash
psql -h localhost -p 5432 -U keycloak keycloak
Benutzerdefiniertes Image und Start mit optimized
- Die Grundkonfiguration verwendet das vorgebaute Image von
quay.io
- Wenn Theme-Anpassungen oder der Start im Modus
--optimized erforderlich sind, wird ein eigenes Image gebaut
- Das Dockerfile verwendet auf Basis des offiziellen Keycloak-Images einen Multi-Stage-Build
- Im Builder-Schritt
ENV KC_DB=postgres setzen
/opt/keycloak/bin/kc.sh build ausführen
/opt/keycloak/ in das finale Image kopieren
ENTRYPOINT ["/opt/keycloak/bin/kc.sh"] festlegen
- In
docker-compose.yml wird dies wie folgt geändert
- Die Zeile
image: entfernen oder auskommentieren
build: . aktivieren
command: start --optimized hinzufügen
- Danach den Docker-Stack herunterfahren, optional einen expliziten Build ausführen und wieder starten
docker compose down
docker compose build
docker compose up -d && docker compose logs --follow
Zusätzliche Anpassungen in der Produktionsumgebung
- Warnungen zu JGroups-bezogenen
MulticastSocket-Empfangspuffern werden gelöst, indem auf dem Host in /etc/sysctl.conf Pufferwerte ergänzt werden
net.core.rmem_max = 26214400
net.core.wmem_max = 1048576
- Zum Übernehmen der Konfiguration
sysctl -p ausführen
- Die Quarkus-Warnung zur XA-Transaktionswiederherstellung wird behoben, indem dem Keycloak-Dienst ein Volume-Mount und eine Umgebungsvariable hinzugefügt werden
- Volume:
/srv/keycloak/data/keycloak/ObjectStore/:/ObjectStore/
- Umgebungsvariable:
QUARKUS_TRANSACTION_MANAGER_ENABLE_RECOVERY: true
- Vor dem Start auf dem Host das ObjectStore-Verzeichnis anlegen und im Container den Besitzer von
/ObjectStore auf Benutzer-ID 1000 ändern
Schritte nach der Konfiguration
- Der Endzustand ist eine Konfiguration, bei der der Keycloak-Dienst in rootless Docker hinter dem System-nginx-Reverse-Proxy läuft und nginx die SSL-Terminierung übernimmt
- Für automatische Container-Updates wird auf das Auto-Update-Verfahren in einem separaten Mastodon-Beitrag verwiesen
- Der nächste Konfigurationsschritt ist das Hinzufügen einer E-Mail im Keycloak-Admin-Console
- Danach können weitere Realms hinzugefügt und Themes konfiguriert werden
- Für Themes können keycloakify und keycloakify-starter verwendet werden
- Das Dockerfile enthält eine auskommentierte Zeile, die ein keycloakify-Theme-JAR nach
/opt/keycloak/providers/ kopiert
1 Kommentare
Meinungen auf Hacker News
Ich habe mich kürzlich für Authelia entschieden, als ich mein Homelab mit Authentifizierung versehen habe
Keycloak funktioniert zwar auch, ist aber viel zu groß, und wenn man es mit traefik forward auth nutzen will, braucht man zusätzliche Services
Authelia hat keine UI zum Bearbeiten von Nutzern und auch keine bidirektionale Synchronisierung mit einem LDAP-Backend-Server, lässt sich aber nur mit statischen Dateien und Umgebungsvariablen konfigurieren und passt deshalb in vielen Fällen gut
Wenn es nur darum geht, einigen Services Authentifizierung hinzuzufügen und dort, wo es möglich ist, SSO einzubinden, lohnt es sich, mit Authelia anzufangen
Wenn ihr SSO, einfache Einrichtung und eine Admin-UI braucht, ist auch FusionAuth einen Blick wert. UI/UX fühlt sich zwar nach Mitte der 2000er an, aber man kann es selbst herunterladen und ausführen[0], es ist Docker-freundlich[1] und bietet mehrere Konfigurationswege[2], etwa die Verwaltung von OIDC oder anderen Einstellungen per Terraform[3]
Es kann kostenlos genutzt werden, ist aber nicht Open Source[4]
0: https://fusionauth.io/download
1: https://fusionauth.io/docs/get-started/download-and-install/...
2: https://fusionauth.io/docs/operate/deploy/configuration-mana...
3: https://fusionauth.io/docs/operate/deploy/terraform
4: https://fusionauth.io/license-faq#28
Ich nutze Caddy als Reverse Proxy und habe es mit Authelia integriert[1], was gut funktioniert
Ich habe alle Services mit solider Zwei-Faktor-Authentifizierung versehen und habe das Gefühl, dass der Zugriff auf meine selbst gehosteten Apps auch ohne VPN ausreichend sicher ist
Allerdings gab es seit über einem Jahr kein neues Authelia-Release mehr, was mir aus Sicherheitssicht Sorgen macht
[0] https://github.com/lldap/lldap
[1] https://www.authelia.com/integration/proxies/caddy/
[1] https://github.com/greenpau/caddy-security
Für Homelab-Umgebungen ist das ein sehr guter Anwendungsfall, besonders wenn man die Funktionen der größeren Lösungen nicht braucht oder nicht will
Ich habe gesucht, aber nichts in Richtung einfaches Schema, JSON oder HTTP gefunden, und ich kann kaum glauben, dass fast alle alles neu gebaut haben, aber niemand LDAP neu erfunden hat
Soweit ich weiß, ist Active Directory faktisch der einzige andere Standard
Außerdem frage ich mich, ob es einen Standard oder ein Protokoll gibt, um Zugriffskontrolle nach außen auszulagern
Authelia kann Zugriffe über URL-Muster steuern, aber bei einem Dateiserver würde ich zum Beispiel erwarten, dass er anhand der authentifizierten Nutzer-ID und eines Schlüssels in der Datenbank beim LDAP-Server die Berechtigungen abfragt
Das wirkt wie die umgekehrte Richtung von OAuth2, bei dem ein Server Zugriffsrechte auf einen Drittanbieter-Service erhält
Ich habe mir kürzlich angesehen, wie ich in meinem Homelab ein relativ einfaches SSO einrichten kann; das Hauptziel war, sich unkompliziert per Google- oder GitHub-Authentifizierung anzumelden.
In einem früheren Job habe ich sowohl JetBrains Hub[1] als auch Keycloak verwendet, und beide waren ziemlich mühsam zu konfigurieren.
JetBrains Hub ließ sich wirklich leicht starten, und so war auch meine frühere Erfahrung, aber es war unpraktisch, dass es im Docker-Registry kein
latest-Tag gibt.Ich weiß, dass das Festpinnen von Versionen gut ist, aber für den privaten Gebrauch möchte man normalerweise alle Docker-Container auf einmal aktualisieren.
Keycloak dagegen war sehr umständlich in Gang zu bringen; im Entwicklungsmodus war es einfach, aber die Produktionskonfiguration hat mich ausgebremst.
Soweit ich mich erinnere, hatte es mit einem Wildcard-Zertifikat von Let's Encrypt zu tun, und nach ein paar Stunden habe ich aufgegeben.
Am Ende habe ich mich für Dex[2] entschieden. Wegen der dürftigen Dokumentation hatte ich es aufgeschoben, aber die eigentliche Einrichtung war sehr einfach: eine einfache YAML-Datei, eine SQLite-Datenbank und eine Subdomain reichten aus.
Ich habe Dex mit dem hervorragenden OAuth2 Proxy[3] und einer eigenen Vorlage für den Nginx Proxy Manager kombiniert, sodass pro internem Dienst eine zweizeilige SSO-Konfiguration genügt, und außerdem ein Dex-Docker-Template[4] für unRAID erstellt.
Dazu habe ich für den Zugriff von außerhalb des Hauses Cloudflare Access und WAF ergänzt, um die Sicherheit zu erhöhen; jetzt möchte ich nur noch CrowdSec hinzufügen, um etwas mehr Einblick zu bekommen.
Persönlich halte ich das für die einfachste Option.
https://github.com/lastlogin-io/obligator
Ich habe eine unvollständige Vergleichstabelle mehrerer selbst hostbarer OpenID-Connect-Server erstellt[0].
Eines der überraschenden Dinge war, dass die Keycloak-Codebasis wirklich riesig ist.
[0]: https://github.com/lastlogin-io/obligator?tab=readme-ov-file...
Die Vorstellung, dass Keycloak Sicherheitsprobleme löst, ist amüsant.
Wenn man sich die CVE-Liste ansieht, versteht man, was ich meine.
Eine geschlossene, intransparente Lösung ohne gemeldete CVEs als „sicher“ zu bezeichnen, wäre ebenfalls lächerlich.
Außerdem gibt es für das aktuelle Release 22.0.2 nur drei bekannte Schwachstellen.
https://www.cvedetails.com/vulnerability-list/vendor_id-25/p...
Allein dass in dem Artikel https://www.keycloakify.dev/ erwähnt wurde, ist sehr nützlich.
Es sieht nach einer hervorragenden Alternative zum Standard-Ansatz für Themes aus.
Ich nutze es seit zwei Jahren und kann nur Gutes darüber sagen.
Der Maintainer reagiert sehr schnell, und kürzlich sind sowohl in Keycloak als auch in keycloakify Änderungen eingeflossen, die die zukünftige Kompatibilität des Theme-Ansatzes verbessern.
Derzeit werden offiziell nur mit create-react-app erstellte Apps unterstützt, aber ein vite-Branch ist in Entwicklung, und ich persönlich nutze es schon seit einiger Zeit mit vite.
Habe authentik[1] und authelia[2] im Blick
Authelia sieht sehr gut aus, aber Keycloak hat einen Connector für Angular, während man bei Authelia zum Beispiel ein OIDC-Angular-Plugin selbst konfigurieren müsste, daher war ich etwas vorsichtig
Trotzdem dürfte der Einstieg einfacher werden, wenn es eine Konfiguration für Keycloak gibt
[1] https://goauthentik.io/
[2] https://www.authelia.com/
Ich schütze dauerhaft mehr als 10 Services in Docker und Kubernetes; wenn man es nicht genießt, die Schutzkonfiguration für jeden Service einzeln vorzunehmen, wird man mit authentik leiden
authentik hat einen schwerwiegenden Bug[0]: Wenn man mehrere Subdomains (app1.example.com, app2.example.com usw.) mit einer einzigen Konfiguration schützt, werden Benutzer nach Ablauf der Session und erneuter Authentifizierung zufällig auf einen anderen Service umgeleitet
[0]: https://github.com/goauthentik/authentik/issues/6886
Das lässt sich nicht ohne Breaking Changes beheben und funktioniert mit vielen Tools, die den cc-Grant verwenden, nicht
Nachdem ich das gesehen hatte, habe ich es komplett von der Kandidatenliste gestrichen
https://github.com/goauthentik/authentik/issues/6139
Wenn ich bei der Angular-Konfiguration helfen kann, unterstütze ich gern über GitHub Discussions
Authentik sah besser aus, aber die in anderen Antworten erwähnten Bugs sehen ziemlich übel aus
Das Problem mit Keycloak ist, dass es ein altes Projekt ist und sich enorm viel verändert hat
Es begann als JBOSS-Projekt, und seine Nützlichkeit als IdP glänzt bei der Authentifizierung von On-Premises-Clustern, aber meiner Meinung nach endet es dort
Ich habe in einer Fortune-500-Abteilung Keycloak in großem Maßstab auf AWS ECS implementiert, und es korrekt zu clustern fühlte sich an wie der Hundertjährige Krieg
DNS-Discovery funktionierte nicht richtig, und die Cluster-Discovery war UDP-basiert, was in Cloud-Umgebungen nicht funktioniert hat
Ein zustandsbehafteter Login auf einem Server war auf einem anderen nicht vorhanden, daher war simples Load Balancing unmöglich; Sticky Sessions waren die einzige Option
Keycloak per
docker runzu starten und wie Auth0 einzustecken ist einfach, aber es fühlt sich an, als würde man einen Ford F-150 Baujahr 1996 mit 250.000 Meilen kaufenEr fährt und funktioniert, aber die Wartung ist wirklich schrecklich
Soweit ich mich erinnere, nutzt die Standard-Discovery Multicast, das in typischen Cloud-Netzwerken oder Swarm-/Kubernetes-Overlay-Netzwerken nicht aktiviert ist
Ich habe auch Database Ping gesehen, das ein RDBMS als eine Art Quorum-Mechanismus nutzt, aber es wirkte sehr fragil und eher wie ein letzter Ausweg
Am Ende konnte ich einen Kubernetes-Cluster-Treiber verwenden, der die Nodes über das DNS des Swarm-Clusters entdeckt
Es war ziemlich mühsam, es zum Laufen zu bringen, aber seitdem ist es meines Wissens stabil
Heutzutage scheint es auch einen nativen EC2-Networking-Treiber zu geben, aber ich habe ihn nicht selbst untersucht
Mich würde interessieren, wann die ECS-Bereitstellung war
Bei uns ist UDP nur für DNS erlaubt
Keycloak ist großartig, kann für Anfänger aber ziemlich verwirrend sein
Es hat viele Funktionen, und die Dokumentation ist nicht die beste
Kürzlich habe ich Zitadel ausprobiert, und es war deutlich einfacher zu benutzen
Allerdings kann man es nicht mit einer eingebauten Datenbank ausführen, daher ist Self-Hosting etwas schwieriger
Künftig geht die Richtung dahin, Postgres als Datenbank zu verwenden; ich hoffe, dass es dadurch einfacher wird, es zusammen mit anderen Tools bereitzustellen
Mein Chef nannte Keycloak kürzlich etwas, „das immer weiter Geschenke macht“, meinte damit aber eigentlich, dass ständig neue Jira-Tickets entstehen, um herauszufinden, wie man etwas tun soll
Trotzdem haben wir Terraform, das einen EKS-Cluster erstellt und Keycloak deployt, SAML-/OIDC-Clients anlegt, externe Identity Provider hinzufügt und sogar einen AWS IAM Identity Provider konfiguriert
Sobald man herausgefunden hat, was man tun kann, wie man es in der UI macht und wie man es mit mrparkers Terraform Provider automatisiert, ist die Nutzung selbst sehr einfach
Ein Freund bräuchte es :)
Nachdem ich Keycloak ein paar Jahre genutzt hatte, war ich ehrlich gesagt all die merkwürdigen Eigenheiten leid und begann, nach Alternativen zu suchen
Mehrere Kandidaten wie Authentik sahen in Ordnung aus, aber Zitadel[1] fiel mir auf, und seitdem habe ich nicht mehr zurückgeblickt
[1] https://zitadel.com/blog/zitadel-vs-keycloak
Mich würde interessieren, was dich letztlich überzeugt hat