Keycloak installation über localhost, aber Server haben doch keine GUI?
Ich möchte Kaycloak auf meinem Ubuntu Docker Cloud Server installieren. Laut Anleitung und Tutorials erstell ich dazu mit selfCertificate ein https Zugang auf localhost:8443
Soweit alles gut. Als Nächstes soll jetzt die Einrichtung über diesen Zugang geschehen. Hier der Denkfehler - ich habe auf meinem Server keine Oberfläche und keinen Browser um die Seite aufzurufen.
Der Aufruf ip:8443 geht nicht. Nur der unverschlüsselte aufruf ip:8080 ging bei diesem meldet keycloak aber sofort "https required"
Was verschweigt mir die Anleitung?
1 Antwort
Dein Problem wird sein, dass Keycloak oder eventuell auch nur der Docker Proxy nur auf localhost aka. 127.0.0.1 lauscht. Dann kann Keycloak auch nur über diese IP Adresse erreicht werden. Da localhost nur lokal zum gewünschten Ort aufgelöst werden kann, kannst du Keycloak nicht erreichen.
In der Keycloak Konfiguration sollte 0.0.0.0 als Bind Adresse stehen. Damit ist Keycloak über alle IP Adressen erreichbar.
Alternativ kannst du auch ein Reverse Proxy Webserver wie z.B. Apache2 oder Nginx nutzen. Der Webserver lauscht dann auf allen IP Adressen und leitet es nach seinem localhost weiter. Darüber könntest du auch HTTPS umsetzen.
Wenn du es wünschst, könnte ich meine Keycloak Konfiguration teilen. Ich nutze dafür Docker Container von Bitnami (PostgreSQL + Keycloak), Docker Compose und Apache2 Webserver für u.A. HTTPS.
docker-compose.yaml
services:
postgresql:
image: docker.io/bitnami/postgresql:11
environment:
# ALLOW_EMPTY_PASSWORD is recommended only for development.
- ALLOW_EMPTY_PASSWORD=yes
- POSTGRESQL_USERNAME=bn_keycloak
- POSTGRESQL_DATABASE=bitnami_keycloak
volumes:
- 'postgresql_data:/bitnami/postgresql'
- /etc/timezone:/etc/timezone:ro
restart: always
keycloak:
image: docker.io/bitnami/keycloak:21
environment:
KEYCLOAK_PRODUCTION: "true"
KEYCLOAK_HOSTNAME: login.example.com # müsste optional sein
KEYCLOAK_PROXY: edge # Wichtig für Reverse Proxy mit HTTPS
KC_FEATURES: docker
depends_on:
- postgresql
ports:
- "127.0.0.1:8088:8080" # bewusst auf localhost gesetzt; extern unter Port 8088
volumes:
- /etc/timezone:/etc/timezone:ro
restart: always
volumes:
postgresql_data:
Weitere hilfreiche Dokumentation: https://www.keycloak.org/server/reverseproxy
Da der Docker Port Proxy bewusst auf 127.0.0.1/localhost läuft, ist der ungesicherte Keycloak Port nur auf dem gleichen Gerät erreichbar. Daher ist für die externe Verbindung ein Reverse Proxy zwingend erforderlich.
Apache2 VirtualHost Config:
<VirtualHost _default_:443>
ServerName login.example.com
ProxyPass / http://127.0.0.1:8088/
ProxyPassReverse / http://127.0.0.1:8088/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/login.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/login.example.com/privkey.pem
# Die Optionen wirst du zu Traefik "übersetzen" müssen; siehe auch verlinkter Doku
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
</VirtualHost>
In einer anderem Apache2 Config Datei werden auch jegliche HTTP Anfragen auf HTTPS umgeschrieben.
Weitere Keycloak Konfigurationen wie Realm, Nutzer, oder OpenID-Connect Clients habe ich über die Admin UI durchgeführt.
Auch wenn ich:
ports:
- "8080:8080"
oder
- "0.0.0.0:8080:8080"
setze kann ich den Server extern nicht erreichen (wie gesagt, Hetzner Server, in diesem Fall Kamatera haben standardmäßig kein GUI). Da der Server nicht mit http://ip:port erreichbar ist, geh ich davon aus, dass mein Server ein Problem hat oder die "KEYCLOAK_PROXY: edge" option verhindert das direkt zugegriffen werden kann.
Die Apache Konfig wird nicht per Volume eingebunden daher geh ich von aus das ein Apache auf dem Server laufen muss der dann mit der Konfig den Container weiterleitet. Ich kann das mal auf einem Testserver probieren. Will allerdings langfristig Traefik laufen lassen und ich denke mal das Apache die Ports 80, 443 besetzen will
Ich hab übersehen das die logs eine Fehlerausgabe bringen:
Keycloak:
keycloak 19:56:16.67 ERROR ==> You need to have TLS enabled. Please set the KEYCLOAK_ENABLE_HTTPS variable to true
Postgres hat nach dem zweiten Start kein Fehler mehr gebracht
Nach Einfügen der variable:
keycloak 19:59:48.13 ERROR ==> Path to the TLS truststore file not defined. Please set the KEYCLOAK_HTTPS_TRUST_STORE_FILE variable to the mounted truststore
keycloak 19:59:48.14 ERROR ==> Path to the TLS keystore file not defined. Please set the KEYCLOAK_HTTPS_KEY_STORE_FILE variable to the mounted keystore
Das klingt jetz wieder nach dem Self Zertifikat das ich generieren kann
Ich hab sie eingebunden:
Allerdings sind alles Sachen die du nicht machen musstest und ich habe ja die Version übernommen, das versteh ich nicht - wo liegt da der Haken?
services:
keycloak:
image: docker.io/bitnami/keycloak:21
environment:
KEYCLOAK_PRODUCTION: "true"
KEYCLOAK_HOSTNAME: login.example.com # müsste optional sein
# KEYCLOAK_PROXY: edge # Wichtig für Reverse Proxy mit HTTPS
KC_FEATURES: docker
KEYCLOAK_HTTPS_TRUST_STORE_FILE : /opt/keycloak/conf/server.crt.pem
KEYCLOAK_HTTPS_KEY_STORE_FILE : /opt/keycloak/conf/server.key.pem
KEYCLOAK_ENABLE_HTTPS: "true"
depends_on:
- postgresql
ports:
- "8080:8080"
- "8443:8443"
volumes:
- /etc/timezone:/etc/timezone:ro
- ./server.crt.pem:/opt/keycloak/conf/server.crt.pem
- ./server.key.pem:/opt/keycloak/conf/server.key.pem
restart: always
volumes und postgres unverändert
Mein Keycloak log:
2023-09-20 15:08:47,065 WARN [org.jgroups.protocols.UDP] (keycloak-cache-init) JGRP000015: the send buffer of socket MulticastSocket was set to 1MB, but the OS only allocated 212.99KB
2023-09-20 15:08:47,064 WARN [org.jgroups.protocols.UDP] (keycloak-cache-init) JGRP000015: the receive buffer of socket MulticastSocket was set to 20MB, but the OS only allocated 212.99KB
2023-09-20 15:08:47,058 WARN [org.jgroups.protocols.UDP] (keycloak-cache-init) JGRP000015: the send buffer of socket MulticastSocket was set to 1MB, but the OS only allocated 212.99KB
2023-09-20 15:08:47,052 INFO [org.jgroups.JChannel] (keycloak-cache-init) local_addr: 793bcf5e-49bc-46af-bb13-ae1c4be3f9b1, name: 17fee143c77f-60994
2023-09-20 15:08:46,021 INFO [org.infinispan.CONTAINER] (keycloak-cache-init) ISPN000556: Starting user marshaller 'org.infinispan.jboss.marshalling.core.JBossUserMarshaller'
2023-09-20 15:08:46,872 INFO [org.infinispan.CLUSTER] (keycloak-cache-init) ISPN000088: Unable to use any JGroups configuration mechanisms provided in properties {}. Using default JGroups configuration!
2023-09-20 15:08:47,038 INFO [org.infinispan.CLUSTER] (keycloak-cache-init) ISPN000078: Starting JGroups channel `ISPN`
2023-09-20 15:08:45,997 WARN [org.infinispan.PERSISTENCE] (keycloak-cache-init) ISPN000554: jboss-marshalling is deprecated and planned for removal
2023-09-20 15:08:49,121 INFO [org.infinispan.CLUSTER] (keycloak-cache-init) ISPN000079: Channel `ISPN` local address is `17fee143c77f-60994`, physical addresses are `[172.22.0.3:46280]`
2023-09-20 15:08:50,106 INFO [org.keycloak.broker.provider.AbstractIdentityProviderMapper] (main) Registering class org.keycloak.broker.provider.mappersync.ConfigSyncEventListener
2023-09-20 15:08:51,532 ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) ERROR: Failed to start server in (production) mode
2023-09-20 15:08:51,532 ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) ERROR: No trust store password provided
2023-09-20 15:08:51,532 ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) For more details run the same command passing the '--verbose' option. Also you can use '--help' to see the details about the usage of the particular command.
2023-09-20 15:08:45,785 WARN [io.quarkus.vertx.http.runtime.VertxHttpRecorder] (main) The X-Forwarded-* and Forwarded headers will be considered when determining the proxy address. This configuration can cause a security issue as clients can forge requests and send a forwarded header that is not overwritten by the proxy. Please consider use one of these headers just to forward the proxy address in requests.
2023-09-20 15:08:45,632 INFO [org.infinispan.SERVER] (keycloak-cache-init) ISPN005054: Native IOUring transport not available, using NIO instead: io.netty.incubator.channel.uring.IOUring
2023-09-20 15:08:41,510 INFO [org.keycloak.quarkus.runtime.hostname.DefaultHostnameProvider] (main) Hostname settings: Base URL: <unset>, Hostname: login.example.com, Strict HTTPS: true, Path: <request>, Strict BackChannel: false, Admin URL: <unset>, Admin: <request>, Port: -1, Proxied: true
2023-09-20 15:08:44,106 WARN [io.quarkus.agroal.runtime.DataSources] (main) Datasource <default> enables XA but transaction recovery is not enabled. Please enable transaction recovery by setting quarkus.transaction-manager.enable-recovery=true, otherwise data may be lost if the application is terminated abruptly
Mein Apache2 Server läuft direkt auf dem Server ohne Docker. Der läuft schon länger auf dem Server als ich Docker nutze. Der bündelt auch meine diversen Webservices auf Port 80 (nur Weiterleitung) und 443. Die Configs dazu liegen dementsprechend auch direkt auf dem System.
Beim Modus "edge" wird erwartet, dass der Reverse Proxy die Verbindung verschlüsselt und Keycloak dann auch eine ungesicherte Verbindung annimt. Dann ist KEYCLOAK_ENABLE_HTTPS auch nicht nötig. Damit ist dann auch kein Zertifikat im Keycloak Container nötig.
Wenn man Zugriff auf dem Server hat, könnte man theoretisch den Traffic lokal abgreifen und auf Passwörter zugreifen.
Es ist auch wichtig, dass die X-Forwarded Header gesetzt werden, wie es auch in der verlinkten Proxy Doku beschrieben wird. Ansonsten kam glaube ich weiterhin die TLS Erforderlich Fehlermeldung.
Zum Thema der Headers gibt es hier ein Teil in der Doku. Da ich keine Erfahrung mit Traefik habe, musst du das selber herausfinden.
Zum Thema Erreichbarkeit von Port 8080 solltest du auf die Spurensuche gehen. Mit Netcat (CLI Programm: nc) lässt sich überprüfen, ob ein TCP Port eine Antwort gibt. Benutzung:
nc -vz localhost 8080
Damit schaust du, ob unter localhost (Domain/IP) und Port 8080 etwas unter TCP läuft.
Da solltest du zuerst Keycloak im Container, dann dein Host System per Docker Proxy und auch von Zuhause über Internet überprüfen. Mögliche Gründe dafür:
- Keycloak deaktiviert Port 8080 wenn direktes TLS aktiviert ist -> TLS Port nutzen
- Software Firewall in Ubuntu -> Port dort freigeben (vermutlich ufw)
- Firewall Lösung von Hetzner -> Hetzner kontaktieren
Mein Server von Netcup hat auch keine GUI bzw. ich brauche auch keine GUI.
Alles klar, da muss ich mich einmal tief in das Thema einarbeiten, danke für die Ausführlichen Erklärungen
Ich habe eine Konfiguration ausführen können, die ein Schlüssel über volume einbindet und mit der ich mich über https://ip:8443/admin einloggen konnte. Allerdings über shell-script und das stieg beim zweiten mal direkt wieder aus.
Soweit ich verstanden hab will Keycloak sein eigenes Zertifikat, so das ich Traefik nicht nutzen kann. Es ist auch in Ordnung wenn es ohne Domaine läuft.
Ja ich mag gern deine Konfiguration sehen.