LML7 - LDAP - SSO via Keycloak SAML / OIDC für Greenlight, Nextcloud, Moodle, Dokuwiki, Bookstack

Hallo :slight_smile:
(wie so oft) zufällig entdeckt, dass man bei der BBB-Installation mit einer Option Keycloak mit installieren kann und schon hat ein mehrtägiges Abenteuer begonnen.
Letztendlich ist eine SSO-Lösung für unsere Schule entstanden. Da es da so einige Stolpersteinchen gab dachte ich versuche hier mal kurz :face_with_hand_over_mouth: mein Vorgehen mit euch zu teilen, damit man da vll. ein paar Minuten Lebenszeit sparen kann :wink:

Realisiert wurde eine BBB-Installation mit Greenlight und Keycloak. Letzteres ermöglicht es den Benutzerstamm aus dem LDAP der LML7 zu holen und dort eine zentrale Benutzer-/Rechte-/Zugriffs-Verwaltung für die über die single sing on Protokolle OIDC oder SAML angebunden Dienste zu ermöglichen.

Dienst SSO-Typ Einschränkungen/Probleme
Greenlight (BBB) OpenID Connect Läuft :white_check_mark:
Nextcloud SAML Läuft :white_check_mark:
Moodle SAML :x: Moodle bekommt zentralen Logout nicht mit. Moodle selbst loggt aber zentral aus.
Dokuwiki OpenID Connect Läuft :white_check_mark:
Bookstack SAML Läuft :white_check_mark:

0. Installation von BigBlueButton inkl. Greenlight und Keycloak

Installation

… läuft auf frischem Ubuntu 22.04 LTS problemlos mit offiziellen Skript durch.

wget -qO- https://raw.githubusercontent.com/bigbluebutton/bbb-install/v2.7.x-release/bbb-install.sh |bash -s -- -v focal-240 -s bbb.example.com -e admin@example.com -g -w -t <key>:<secret>

(BigBlueButton : LTI)
das -g ist für greenlight, -k für keycloak
(Install Greenlight v3 | BigBlueButton)

Die Optionen <key> und <secret> habe ich zunächst aus den alten BBB-Instanz übernommen.
<key> = bbb
<secret> findet man mit bbb-conf --secret ganze ist mit bbb-conf --lti überprüfbar.
(Falls relevant: Habe beim ersten Durchlauf ohne -g -w -t <key>:<secret> installiert - weil nicht gelesen :face_with_peeking_eye: - und beim zweiten Durchlauf dann wie oben.)

(Install BigBlueButton | BigBlueButton)
(GitHub - bigbluebutton/bbb-install: BASH script to install BigBlueButton in 30 minutes.)

Update/Upgrade

Installationsskript einfach nochmal ausführen…

BBB Befehle

bbb-conf --restart #Neustarten...
bbb-conf --status #Aktueller Status der Dienste
dpkg -l | grep bbb- # Auflistung aller core BigBlueButton Packete

Standard Präsentation anpassen

cp default.pdf /var/www/bigbluebutton-default/assets/default.pdf

(Für die Moodle-Räume geht das auch via Moodle-Plugin-Einstellungen…)

BBB Moodle-Integration

Dafür brauchts dieses Addon in Moodle.
(Moodle Plugins directory: BigBlueButtonBN | Moodle.org)
Und das Secret aus BBB.

cat /usr/share/bbb-web/WEB-INF/classes/bigbluebutton.properties | grep Salt

oder

bbb-conf --secret

In den Einstellungen des Moodle-Plugins dann
BigBlueButton-Server-URL (bigbluebuttonbn_server_url): https://bbb.example.com/bigbluebutton/
und
BigBlueButton Shared Secret bigbluebuttonbn_shared_secret: geheimgeheimgeheim
eingeben und anpassen,was man so mag, das war es auch schon :slight_smile: .

1. Keycloak - Grund-Konfiguration / LDAP

Habe mich im wesentlichen hier orientiert: (External Authentication | BigBlueButton)
Ich übernehme mal deren WICHTIGER HINWEIS: Dies ist eine Beispielkonfiguration, die zum Testen verwendet werden soll. Für ein komplettes Produktionsset lesen Sie bitte Keycloaks Dokumentation.

  1. Administratorpanel aufrufen: https://bbb.example.com/keycloak/admin

  2. Neuen „Realm“ anlegen, indem man in der linken oberen Ecke auf den Master Realm klickt, dann auf Create Realm.
    grafik

  3. Als Realm name / Realm ID besten was neutrales nehmen, wie lml-ldap oder so… nacher ändern macht viel Arbeit, weil das in alle Links eingebaut wird.

  4. Unter User federation die Option Add LDAP providers auswählen.


    Vorbereitend muss man auf seiner LML einen bind-user z.B. keycloak-binduser anlegen. Eine sehr gute Anleitung dazu gibt es hier in der tollen LML-Doku (Externe Authentifizierung - Nextcloud — linuxmuster.net latest Dokumentation)
    Dieser binduser hat nur read-only Berechtigungen, d.h. wenn ihr in den LDAP schreiben wollt z.B. für Passwortänderungen, dann braucht ihr einen global-admin Account dazu.

    (Wir haben den BBB-/Keycloak-Server via VPN an die LML getunnelt; IP/Domain entsprechend anpassen… und wenn über öffentl. Netz natürlich auch Verschlüsselung Enable StartTLS aktivieren)

    Die Einstellungen wann da was synchronisiert wird kann man natürlich mal überdenken :slight_smile:. Der restliche Teil darunter ist alles deaktiviert. Speichern nicht vergessen.

  5. Mappers („Datenzuordnung“) anlegen.


    Die wesentlichen sind schon da, wir haben noch folgende dazu angelegt:

Spalte 1 Spalte 2 Spalte 3 Spalte 4
homeDirectory user-attribute-ldap-mapper homeDirectory homeDirectory
sophomorixAdminClass user-attribute-ldap-mapper sophomorixAdminClass sophomorixAdminClass
und für die Gruppen-Zuordnung (Klassen, Lehrer usw.):

Im Anschluss kann man mal einen Sync wagen :slight_smile:
grafik

Danach kann man unter Benutzer und Groups das Ergebnis prüfen. Nicht wundern, Ausgabe bleibt leer, man muss suchen oder * als Platzhalter :slight_smile:


Unter den Reitern Attribute und Groups kann man mal vergleichen ob der Sync passt.

Ggf. gleich mal spielen, Attribute löschen, nochmal den Sync anstoßen und gucken was passiert usw. was man halt so testen mag :innocent:

2 Greenlight

2.1. Client anlegen / Zugang für Dienst in Keycloak einrichten

Anleitung basiert im wesentlichen von hier: (External Authentication | BigBlueButton)
Neuen Client anlegen.



Die Client-ID ist nicht mehr änderbar. Display in der Keycloak-Konsole (https://bbb.example.com/keycloak/realms/lml-ldap/account/), damit die User dort ein Lesezeichen zum Dienst angezeigt bekommen…

Spannendwerweise muss man die Client authentication aktivieren.

Front channel logout sollte man überprüfen, dass das auch aktiviert ist, damit man auch bei Greenlight ausloggt wird, wenn man sich bei keycloak ausloggt.

2.2 Anpassen der Greenlight Einstellungen zur Registrierung


Admin-Gui: https://bbb.example.com/admin/site_settings Man sollte hier darauf achten, dass Keycloak-User auch angelegt werden können, indem man die Offene Registrierung zulässt. Keine Sorge, die Registrierung auf der Webseite funktioniert nach dem nächsten Schritt nicht mehr…

2.3. Anpassen der Greenlight Setup auf dem BBB-Server

Tipp zu Beginn… zum Testen… peinlicher als sich selbst auszusperren und so…
Als Admin erstmal mit Browser 1 sich einloggen (und bleiben). Dann Setup usw ändern und das mit zweitem Browser (privater Modus geht auch…) den Login testen…

nano /root/greenlight-v3/.env

(Kann sein, dass der Pfad variiert, je nach dem wo mann das bbb-install-Skript ausgeführt hat.)

### EXTERNAL AUTHENTICATION METHODS
OPENID_CONNECT_CLIENT_ID=greenlight
OPENID_CONNECT_CLIENT_SECRET=<YOUR_SECRET>
OPENID_CONNECT_ISSUER=https://bbb.example.com/keycloak/realms/lml-ldap
OPENID_CONNECT_REDIRECT=https://bbb.example.com/
OPENID_CONNECT_UID_FIELD=email

(Wenn man schon gerade in der Setup/.env ist kann man dort auch gleich noch die SMTP-Konfiguration für E-Mail-Benachrichtigungen bzw. Zugangsdaten für einen E-Mail Account hinterlegen)
Das Client secret gibt in den Client-Einstellungen


Den <ISSUER_URL> gibt es ein den Realm-Einstellungen

Dann:

  1. Greenlight neustarten um Änderungen zu übernehmen
docker-compose -f greenlight-v3 down
docker-compose -f greenlight-v3 up -d

Oh, so kurz ist das wohl doch nicht :wink:, der Rest folgt die Tage.
Liebe Grüße
Tobi

5 „Gefällt mir“

3. Dokuwiki via Keycloak

3.1 Keycloak - Client anlegen

  1. Im entsprechenden Realm neuen Client dokuwiki mit Client type OpenID Connect anlegen

    Auch hier wieder Client authentication aktivieren.
  2. nachfolgendes vervollständigen:
    Root URL: https://doku.example.com/
    Home URL: https://doku.example.com/
    Valid redirect URIs: https://doku.example.com/*

    Wieder darauf achten, dass Front channel logout aktiviert ist, damit Dokuwiki den Logout via Keycloak mitgeteilt bekommt.
    grafik
  3. Client secret für die spätere Konfiguration in Dokuwiki:
  4. Client scopes anlegen/prüfen
    ClientsdokuwikiClient scopesdokuwiki-dedicated
    Add mapperBy configuration
    Type(Name in der Auswahl): User Realm Role
    Name: groups
    Token Claim Name: groups
  5. Gruppe admin für Dokuwiki-Admins anlegen.
    Ich habe das als Realm-Rolle realisiert, da ich die gleichen Personen/Gruppe auch für andere Systeme zu Admins machen möchte und das in Keycloak dann leicht zu vererben ist. Somit pflegt man in der Theorie dann nur noch einmal in Keycloak die Admin-User/Rechteverwaltung und nicht mehr je Dienst.
    Realm-RollenCreate role
    grafik
    Danach entweder unter Groups eine ganze bestehende LDAP-Gruppe via Role mappingAssign role und die Realm-Rolle admin auswählen oder eine neue Gruppe dafür erstellen, oder unter Benutzer einzelne User via Role mappingAssign role und zur Realm-Rolle admin hinzufügen.

3.2. Dokuwiki konfigurieren

Zugangsverwaltung vorbereiten

Unter AdminZugangsverwaltung lassen sich die Rechte der jeweiligen Nutzer einstellen.
Das sollte man entsprechend seiner Rollen des LDAP anpassen. Bei LML gibts da u.a. teachers und students. Diese entsprechend anlegen und einstelllen, wo/was sie dürfen. Zunächst Gruppe(n) anlegen:


Dann konfigurieren:

Plugins installieren

  1. (plugin:oauth [DokuWiki])
  2. (plugin:oauthkeycloak [DokuWiki])

SSO konfigurieren

Unter AdminKonfiguration
(https://dokuwiki.example.com/doku.php?id=start&do=admin&page=config)

  1. Passen wir im Bereich PluginsoAuth wie folgt an:
    grafik
  2. Anschließend im Bereich PluginsOauthkeycloak
    Client ID: dokuwiki
    Cient Secret: geheimgeheim
    OpenID Connect Auto Discovery URL: https://bbb.example.com/keycloak/realms/lml-ldap/.well-known/openid-configuration
    Und noch irgendeine Bezeichnung, die beim Login angezeigt werden soll: SSO-Login
  3. Zum Abschluss noch im Bereich Authentifizierung auf oauth umstellen.
    grafik
  4. Die Authentifikations-Timeout noch runter setzen (damit er auch checkt ob zwischenzeitlich vll. ein Logout via Keycloak stattgefunden):
    grafik
3 „Gefällt mir“

4. Bookstack (https://bookstackapp.com)

Habe es selbst mit Hilfe des schönen ~30 min Video vom Entwickler (EN) selbst gemacht und durch das Debugging, dass er zeigt das ganze erstmal verstanden :sweat_smile:: (Setting up SAML2 Authentication on BookStack - Foss.video)
Dazugehörige Doku-Seite (SAML 2.0 Authentication · BookStack)
Hier habe ich auch noch geschaut: (Bookstack - Admin Guide)

4.1 Keycloak - Client anlegen

  1. Anders als bei OpenID Connect besteht die Client-ID bei SAML aus einer URI; die nicht nachträglich geändert werden kann.
    Client type: SAML
    Client-ID: https://wiki.example.com/saml2/metadata

    Im nächsten Fenster
    Root URL: https://wiki.example.com/
    Home URL: https://wiki.example.com/
    Valid redirect URIs: https://wiki.example.com/*
    vervollständigen:
    grafik
  2. Client scopes bzw. Mappers anlegen/prüfen
    Clientshttps://wiki.example.com/saml2/metadataClient scopeshttps://wiki.example.com/saml2/metadata-dedicated
    Und dann via Add mapperBy configuration die Werte für email, username usw. verknüpfen.






4.2 Bookstack konfigurieren

Bookstack-Rollen mit Keycloak/LDAP-Gruppen verknüpfen

Dazu geht man in Bookstack auf EinstellungenRollen dann auf die entsprechende Rolle z.B. Admin und gibt unter Externe Authentifizierungs-IDs den Namen der zu verknüpfenden Keycloak/LDAP-Gruppe ein.

SSO via SAML einstellen

Dazu muss die Konfigurationsdatei via Terminal angepasst werden.
Diese liegt in Bookstack unter www/.env je nach Installation kann das variieren… Beispiel bei Docker-Compose im root-Home:
nano /root/docker-bookstack/bookstack_app_data/www/.env

Den Abschnitt habe ich direkt nach dem Block # General auth eingefügt. Und abweichend von der Original-Doku Anpassungen wegen unserem LML-LDAP vorgenommen:

######### SAML2  ######
# Set the display name to be shown on the login button.
# (Login with <name>)
SAML2_NAME="LML-SSO"

# Name of the attribute which provides the user's email address
#SAML2_EMAIL_ATTRIBUTE=user.email
SAML2_EMAIL_ATTRIBUTE=email 

# Name of the attribute to use as an ID for the SAML user.
#SAML2_EXTERNAL_ID_ATTRIBUTE=user.username
SAML2_EXTERNAL_ID_ATTRIBUTE=id

# Name of the attribute(s) to use for the user's display name
# Can have mulitple attributes listed, separated with a '|' in which
# case those values will be joined with a space.
# Example: SAML2_DISPLAY_NAME_ATTRIBUTES=firstName|lastName
# Defaults to the ID value if not found.
#SAML2_DISPLAY_NAME_ATTRIBUTES=user.username
SAML2_DISPLAY_NAME_ATTRIBUTES=first_name|last_name

# Identity Provider entityID URL
SAML2_IDP_ENTITYID=https://bbb.example.com/keycloak/realms/lml-ldap

# Auto-load metatadata from the IDP
# Setting this to true negates the need to specify the next three options
SAML2_AUTOLOAD_METADATA=false

# Identity Provider single-sign-on service URL
# Not required if using the autoload option above.
SAML2_IDP_SSO=https://bbb.example.com/keycloak/realms/lml-ldap/protocol/saml

# Identity Provider single-logout-service URL
# Not required if using the autoload option above.
# Not required if your identity provider does not support SLS.
SAML2_IDP_SLO=https://bbb.example.com/keycloak/realms/lml-ldap/protocol/saml

# Identity Provider x509 public certificate data.
# Not required if using the autoload option above.
SAML2_IDP_x509="geheimgeheim"

# Enable SAML group sync.
SAML2_USER_TO_GROUPS=true

# Set the attribute from which BookStack will read groups names from.
SAML2_GROUP_ATTRIBUTE=groups

# Remove the user from roles that don't match SAML groups upon login.
# Note: While this is enabled the "Default Registration Role", editable within the 
# BookStack settings view, will be considered a matched role and assigned to the user.
SAML2_REMOVE_FROM_GROUPS=true

# Option to dump out SAML 2.0 user details as JSON.
# Only for debugging purposes since it will prevent login.
#SAML2_DUMP_USER_DETAILS=true

Das SAML2_IDP_x509 gibts in den Realm-Einstellungen eures lml-ldap realms



Beim Einfügen darauf achten, dass dieser vollständig ist und ihn in der .env schön in Anführungszeichen SAML2_IDP_x509="geheimgeheim" setzen :smiling_face:

Anschließend passen wir die Authentifizierungsmethode an:

# General auth
#AUTH_METHOD=ldap         #Falls LDAP vorher genutzt....
AUTH_METHOD=saml2
#AUTH_METHOD=standard     #Standard-Methode mit Bookstack eigenen Usern

Bookstack ist da sehr cool, die Änderung ist direkt live und braucht nur im Browser zu aktualisieren ggf. inkl Cache [alt] + [F5] zum Neuladen. Bei Problemen gerne das Debugging via #SAML2_DUMP_USER_DETAILS=true nutzen.

2 „Gefällt mir“

5. Nextcloud

5.1 Nextcloud vorbereiten

  1. App SSO & SAML authentication installieren

    Danach zu den VerwaltungseinstellungenSSO & SAML-Autorisierung und dort Integrierte SAML-Autorisierung benutzen auswählen:
    grafik

Nextcloud warnt hier schonmal:
grafik
Link https://nextcloud.example.com/login?direkt=1 schonmal für den Fall der Fälle merken :slight_smile:

Das Ausfüllen ist etwas wild.
Vorab, es wird bissel was ausgefüllt, dann wird eine Konfigurationsdatei heruntergeladen, diese dann in Keycloak hochgeladen und dann wieder etwas aus Keycloak in die Nextcloud-Konfiguration kopiert… Los gehts

Nextcloud-Konfiguration vor-ausfüllen
Die beiden ersten Häkchen sind abhängig davon, ob ihr eure Benutzer bereits via LDAP in die Nextcloud eingebunden habt und lieber nix unerwartetes wollt :sweat_smile:… beide mal setzen.
dann zuerst mal auf + Autorisierungsdienst hinzufügen die visualisierung ist da bissel seltsam… legt erstmal was an sonst müsst ihr das Nachfolgende nochmal eingeben…
Attribut: username
Name: SSO-Login
Identifikationsmerkmal …: https://bbb.example.com/keycloak/realms/lml-ldap
URL-Ziel …: https://bbb.example.com/keycloak/realms/lml-ldap/protocol/saml


Danach mal die ganzen Menüs ausklappen (siehe Bild die drei roten Pfeile)

  • Daten des Autorisierungsdienstes aufgeklappt:
    URL-Adresse …: https://bbb.example.com/keycloak/realms/lml-ldap/protocol/saml

    Wichtig! Das muss dazu!
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

Jetzt Sind wir soweit, dass unten nun Metadaten gültig in grün stehen sollte und wir die Metadaten-XML herunterladen können.
grafik

5.2 Keycloak - Client importieren

  1. Diesmal legen wir den Client nicht selbst an, sondern importieren die eben von der von Nextcloud erzeugte metadaten.xml


  2. Im nächsten Schritt passen wir an:
    Root URL: https://nextcloud.example.com/
    Home URL: https://nextcloud.example.com/
    Valid redirect URIs: https://nextcloud.example.com/*
    (In der Metadaten.xml steht bei Valid redirect URIs eigentlich https://nextcloud.example.com/apps/user_saml/saml/acs ich habe das angepasst, weiß nicht mehr warum… :sweat_smile:)
    Unter Signature and Encryption
    Sign assertions aktivieren
    grafik

  3. Client scopes bzw. Mappers anlegen/prüfen
    Clientshttps://nextcloud.example.com/apps/user_saml/saml/metadataClient scopeshttps://nextcloud.example.com/apps/user_saml/saml/metadata-dedicated
    Und dann via Add mapperBy configuration die Werte für email, username usw. verknüpfen.

username
name: username
        maper type: user property
        property: username
        SAML attribute name: username
        SAML attribute NameFormat: basic
    email
        name: email
        maper type: user property
        property: email
        SAML attribute name: email
        SAML attribute NameFormat: basic
    nextcloudquota
        name: nextcloudquota
        maper type: user property
        property: nextcloudquota
        SAML attribute name: nextcloudquota
        SAML attribute NameFormat: basic
    Roles
        name: Roles
        mapper type: Role List
        Role attribute name: Roles
        Friendly name: roles
        SAML Attribute NameFormat: Basic
        Single Role Attribute: On





  1. Zertifikat und private Key erzeugen
    Schritt1:


    Beim Klick auf Generate wird direkt der private.key heruntergeladen
    Und dann das Zertifikat angezeigt. Mit Confirm bestätigen.

    Im Anschluss könnt ihr das Zertifikat schon mal kopieren für den nächsten Schritt.

5.3. Nextcloud final konfigurieren

Das Kopierte Zertifikat kommt nun in den aufgeklappten Bereich von Diensteanbieter-Daten unter X.509-Zertifikat des Service-Providers und in das nachfolgende Feld Privater Schlüssel des Diensteanbieters kommt der Inhalt des heruntergeladenen private.key.
grafik

Das sollte es gewesen sein, viel Spaß beim Testen :smiley:

Verwendete Quellen:
https://www.muehlencord.de/wordpress/2019/12/14/nextcloud-sso-using-keycloak/

3 „Gefällt mir“

Keycloak und Zwei-Faktor-Authentifizierung 2FA / MFA

WebAuth Authenticator / Sicherheitsschlüssel / Security-Token (z.B. via Yubikey) aktivieren

  1. Neuen Flow anlegen / Flow duplizieren
    Unter Authentifizierungdirect grant (im Reiter Flows) duplizieren
  2. im duplizierten Flow einen weiteren Schritt/Step bei Conditional OTP hinzufügen

    WebAuthn Authenticator auswählen

    Den neuen Step ggf. eins hoch schieben, dann den Step auf Alternative und auch den OTP-Step auf Alternative umstellen. Anschließend den Flow aktivieren in dem man auf Bind flow
    klickt und dort den Direct grant flow auswählt.

    grafik
  3. Genau das Gleiche nochmal für den Flow browser. Also Flow browser duplizieren, WebAuthn hinzufügen usw.

2FA Pflicht für bestimmte Benutzergruppe einrichten.

Da habe ich viel herumprobiert…
Auch hier wieder den Flow browser kopieren…



Hoffe die Bilder reichen zum Nachbauen aus :innocent:

4 „Gefällt mir“

Hallo @Tobi

vielen Dank für die coole Zusammenstellung/Dokumentation!!

Unser Keycloak ist dieses Jahr erstmals produktiv im Einsatz und wir binden derzeit einen Dienst nach dem anderen an. Moodle/Nextcloud haben wir per OIDC angebunden, das mit dem zentralen Logout haben wir derzeit aber auch (wobei ich da auch noch nicht zum debuggen gekommen bin).

Geplant ist da noch eine Menge (z.B. ein Registrierungsworkflow für Eltern, welcher die derzeitige Moodle-Registrierung ersetzt).

Zusätzlich bilden wir unsere Moodle-Struktur (Klassen/Gruppen) in Keycloak ab - leider wird das in der Regel derzeit nicht automatisch übertragen, das machen wir für unsere Dienste nach wie vor via REST, nur jetzt eben mit Keycloak als Quelle (die wir ebenfalls per Skript aus der Schulverwaltung füttern. Was total nett ist: Keycloak ist sehr flexibel was Attribute oder z.B. verschachtelte Gruppen angeht. Das erspart uns die (derzeit noch separate) Datenbank, in der wir diese Informationen abgebildet haben und ist in Teilen auch z.B. von der Schulverwaltung editierbar.

Auf jeden Fall ist Keycloak ein großer Schritt nach vorn.

Viele Grüße
Thomas

Hallo @Tobi,

vielen Dank für Deine herausragende Arbeit und v.a. extrem wertvolle Dokumentation derselben! Das ist mal wieder echt ein Highlight in diesem Forum!

Ich hatte keycloak auch vor längerer Zeit schon mal „angespielt“, war dann aber irgendwo in der zunächst doch recht unübersichtlichen Welt „verkommen“. Deine Posts habe ich jetzt zum Anlass genommen, dieses überaus sinnvolle und hilfreiche Thema mal wieder zu verfolgen und habe auch Dank Deiner Doku die erste Applikation (Bookstack) an Keycloak angebunden!

Da ich bisher keinen BBB-Server betreibe und wg. der Infos im Nachbarthread jetzt noch auf v3.0 warte (und obendrein gern meine Applikationen getrennt mag), habe ich mich für einen separaten keycloak als Docker entschieden.

Wer das auch machen möchte (und als Doku für mich), hier mein docker-compose (alles in <> ist zu ersetzen):

services:
  keycloak_web:
    image: quay.io/keycloak/keycloak:latest
    container_name: keycloak_web
    environment:
      KC_DB: postgres
      KC_DB_URL: jdbc:postgresql://keycloakdb:5432/keycloak
      KC_DB_USERNAME: keycloak
      KC_DB_PASSWORD: <geheim>

      KC_HOSTNAME: <deine_keycloak_url>
      KC_HOSTNAME_PORT: 8080
      KC_HOSTNAME_STRICT: false
      KC_HOSTNAME_STRICT_HTTPS: false
      KC_HTTP_ENABLED: true
      KC_PROXY_HEADERS: xforwarded
      KC_PROXY_ADDRESS_FORWARDING: true

      KC_LOG_LEVEL: info
      KC_METRICS_ENABLED: true
      KC_HEALTH_ENABLED: true
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: <geheim>
    command: start-dev
    depends_on:
      - keycloakdb
    ports:
      - 8081:8080

  keycloakdb:
    image: postgres:15
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD: <geheim>

volumes:
  postgres_data:

Mein keycloak-Docker steht dabei hinter einem Reverse Proxy (Nginx Proxy Manager - ebenfalls ein Docker), dem man unter „Advanced“ noch folgendes mitgeben muss:

proxy_set_header X-Forwarded-For $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection ‘upgrade’;
proxy_set_header Host $host;

Vielen Dank nochmal!
Jens

1 „Gefällt mir“

Hallo zusammen,
wie der Zufall es wollte, habe auch ich gerade keycloak ausprobiert. Ich bin allerdings den Weg aus dem Nachbarthread gegangen und habe es direkt als LXC-Container aufgesetzt.

Unter Proxmox ist das wirklich nur ein Einzeiler – danach läuft das! :+1:
bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/keycloak.sh)"

Viele Grüße,
Michael

Hi.
Ich bin Deiner Anleitung (zumindest dem Anfang) gefolgt und habe unseren frisch installierten keycloak-Server relativ schnell dazu gebracht, die User zu synchronisieren. Das lief dank Deiner Anleitung alles reibungslos. :+1:

Bei mir sieht die Einstellung unter ldap:// so aus:

Auf diese Art liefert der Button „Verbindung testen“ grünes Licht! Wenn ich StartTLS aktiviere, muss man natürlich den FQDN und nicht mehr die IP nehmen. Das klappt hier auch. Was nicht klappt ist ldaps:// einzutragen … das scheint aber so richtig zu sein, wenn man StartTLS verwendet, oder?

Die Einstellung darunter sieht hier etwas anders aus als bei Dir:
Ich kann den Punkt "Only for ldaps" (wie in Deinem Screenshot zu sehen) gar nicht wählen. Es gibt hier nur "Always" oder "Never" – liegt das evtl an einer anderen keycloak-Version?

Bei den Gruppen werden im Moment meiner Meinung nach viel zu viele Gruppen gemappt. Eigentlich will man ja sowas wie attic und die registrierten Geräte nicht da drin haben, oder?
Danke nochmal.
Viele Grüße,
Michael

Hallo @Jens ,
vielen Dank für die freundliche Rückmeldung :slight_smile:

Die BBB-Jungs lösen die greenlight- und keycloak-Installation auch via Docker. Über das bbb-install.sh Skript landet alles in einer greenlight-v3/docker-compose.yml
Zur vollständigkeit packe ich die hier mal mit rein:

version: '3'

services:
  postgres:
    image: postgres:14.6-alpine3.17
    container_name: postgres
    restart: unless-stopped
    volumes:
      - ./data/postgres/14/database_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=****

  redis:
    image: redis:6.2-alpine3.17
    container_name: redis
    restart: unless-stopped
    volumes:
      - ./data/redis/database_data:/data

  greenlight-v3:
    entrypoint: [bin/start]
    image: bigbluebutton/greenlight:v3
    container_name: greenlight-v3
    restart: unless-stopped
    env_file: .env
    ports:
      - 127.0.0.1:5050:3000
    logging:
      driver: journald
    volumes:
      - ./data/greenlight-v3/storage:/usr/src/app/storage
    depends_on:
      - postgres
      - redis

  keycloak:
    command: start
    image: quay.io/keycloak/keycloak:20.0
    container_name: keycloak
    restart: unless-stopped
    environment:
      - KEYCLOAK_ADMIN=admin
      - KEYCLOAK_ADMIN_PASSWORD=****
      - KC_DB=postgres
      - KC_DB_URL_HOST=postgres
      - KC_DB_USERNAME=postgres
      - KC_DB_URL_DATABASE=keycloakdb
      - KC_DB_PASSWORD=****
      - KC_HOSTNAME_STRICT=false
      - KC_HTTP_RELATIVE_PATH=/keycloak
      - KC_PROXY=edge
    ports:
      - 127.0.0.1:5151:8080
    logging:
      driver: journald
    depends_on:
      - postgres

Hi @Michael ,

  1. bzgl. ldaps://
    bin ich mir nicht sicher, aber ich nehme an, dass wen der Button StartTLS aktivieren aktiviert ist wird er automatisch auf ldaps gehen… das war glaube ich in nextcloud oder so auch so, dass man nur ldap:// verwendet. :thinking:

  2. bzgl. "Only for ldaps"
    ja kann sein… ist keycloak 20 (habe die docker-compose von bbb eben noch gepostet.)

  3. bzgl. Gruppen
    Ja / Nein, Philosophie? Habe ich mir weniger Gedanken gemacht. Fande es eigentlich mal ganz schön endlich durch all diese wilden LML-LDAP-Gruppen durchstöbern zu können :sweat_smile:. Zur Übersicht kann es aber sicherlich ganz geschickt sein den LDAP Filter beim group-ldap-mapper anzupassen.
    Da kann ich dann wieder auf die schöne LML-Dokumentation zur LDAP/Nextcloud-Integration verweisen. Die würden als Filter z.B:
    (&(objectclass=group)(!(|(cn=attic)(cn=wificlass)))(|(cn=teachers)(cn=role-student)(memberof=CN=students,OU=Students,OU=default-school,OU=SCHOOLS,DC=linuxmuster,DC=lan)(sophomorixType=project)))
    nutzen…

Liebe Grüße
Tobias

1 „Gefällt mir“

Hallo zusammen,

… da geht man mal 3 Wochen in Urlaub, und wenn man zurück kommt, dann ist die Doku für das Projekt des nächsten Schuljahres da … ihr seid die Besten!

LG
Holger

6. Zammad

Dachte erst das wird einfach, aber wieder viel herumprobieren…

6.1 Keycloak - Client importieren

  1. Um Zammad als Client hinzuzufügen, speichern Sie die XML-Konfiguration auf Ihrem Rechner (https://zammad.example.com/auth/saml/metadata). Das geht z.B. durch markieren des Links + Rechtsklick + Ziel speichern unter… oder Inhalt der Seite kopieren und in eine metadata.xml Datei abspeichern.

  2. Anschließend verwenden Sie Clients > Clients list > Import client im Keycloak Admin Panel.
    grafik

  3. Im nächsten Schritt passen wir an:
    Root URL: https://zammad.example.com/
    Home URL: https://zammad.example.com/
    Valid redirect URIs: https://zammad.example.com/auth/saml/callback


    Unter Signature and Encryption
    Sign assertions aktivieren
    grafik

  4. Client scopes bzw. Mappers anlegen/prüfen
    Clientshttps://zammad.example.com/auth/saml/metadataClient scopeshttps://zammad.example.com/auth/saml/metadata-dedicated
    grafik



    grafik
    grafik

  5. „Keys“ - Bereich Signing keys config & Encryption keys config (Zertifikat/Priv Key…)
    Das hat mich am meisten Nerven gekostet… deshalb hier der Tipp das erstmal überspringen und zum Testen erst mal zu deaktivieren…

6.2 Zammad - Konfigurieren

Konfiguration findet Ausschließlich im Bereich https://zammad.example.com/#manage EinstellungenSicherheitAnwendungen von Drittanbietern statt.

  1. Frust ersparen, wenn man bereits User angelegt hat; die Automatische Kontoverbindung aktivieren, sonst muss jeder User das aufwendig/versteckt in seinem Profil manuell verknüpfen.

  2. Anmeldung über SAML konfigurieren


    Name Identifier Format: urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
    UID Attribut-Name: id
    Zunächst würde ich Signieren & Verschlüsseln deaktivieren um es als Fehlerquelle auszuschließen.
    grafik
    mit Übermitteln bestätigen und dann kann getestet werden.

6.3 Signieren & Verschlüsseln

Das hat bei mir leider nicht auf anhieb funktioniert… die von Keycloak generierten Zertifikate und Keys will Zammad (wie auch Moodle) nicht nutzen.
Ich habe mir damit beholfen selbst lokal oder aufm server welche zu generieren…

  1. Key + Zertifikat erzeugen
    openssl genpkey -algorithm RSA -out private.key -aes256
    Dabei soll man ein passwort/secret eingeben, dass sollte man sich natürlich merken…
    openssl req -new -key private.key -out request.csr
    openssl x509 -req -days 36500 -in request.csr -signkey private.key -out certificate.crt
    (Ja ich habe das gleich für 100 Jahre Gültigkeit erzeugt…)
    Danach hat man die Dateien private.key und certificate.crt

  2. Inhalte von private.key und certificate.crt sowie das secret in der Konfiguration von Anmeldung über SAML ergänzen und mit Übermitteln bestätigen

  3. Das Zertifikat in Keycloak importieren. Was etwas wild ist…
    Wir lassen zunächst Keycloak eines generieren, denn erst danach können wir das certfile direkt importieren…
    grafik





    :exclamation: Das gleiche nochmal für Encryption keys config :exclamation:
    grafik

Optional: Wenn man nurnoch Login via SAML nutzen will:
Im Bereich https://zammad.example.com/#manage EinstellungenSicherheitBasis
Passwort-Anmeldung auf nein

Weiterführende Gedanken…
Also bei bereits bestehendem User-Stamm via LDAP funktioniert das so prima, die Schülerschaft kommt zwar rein, aber sieht halt nur ihre eignen Tickets. Die Agenten-Zuweisung ist via LDAP-Gruppe teachers gemacht… kann natürlich bei euch anders sein :exclamation: Testen, bevor eure Tickets von Schüler*innen beantwortet werden :joy::exclamation:

Das sollte es gewesen sein. Viel Erfolg beim Testen :nerd_face: und liebe Grüße
Tobi

Verwendete Quelle: SAML — Zammad Admin Documentation documentation

1 „Gefällt mir“

Hallo zusammen,

@Tobi Ich hab mich ja schon als Fan Deiner Arbeit und Doku geoutet. Ganz tolle Sache! Vielen Dank nochmal für das Teilen Deiner Erfahrungen und Anleitungen!

Mal so nebenbei in die Runde gefragt: die mitgelieferten Themes entbehren ja nicht einer gewissen Hässlichkeit. Ich bin aber kein talentierter Web-Mensch. Ein neues Theme habe ich angelegt bekommen, aber hat schon jemand (zumindest mal den Login-Screen) umgestaltet und würde seine entsprechenden Dateien teilen? So richtig einfach scheint das ja nicht zu sein, so lang man nicht der Herr jedes CSS-Details ist … es gibt ja sogar ein Projekt zum Erstellen von Keycloak-Themes (keycloakify), aber so richtig selbsterklärend ist auch das nicht (finde ich zumindest).

Beste Grüße,
Jens

Tobi,

eine Frage zu den Flows mit 2FA für Lehrer und ohne für alle anderen (Link): im letzten Schritt bekomme ich bei mir die Condition „user role config“ nicht so wie Du konfiguriert. Die „User role“ teacher gibt es bei mir nicht. Wo bekomme ich die denn her?

In der zweiten Condition müssen es dann vermutlich „students“ sein, richtig?

DANKE!
Jens

:wave: @Jens

  1. Bzgl. Keycloak-Theme / CSS… damit habe ich mich leider noch nicht beschäftigt; steht aber definitiv noch an.

  2. Bzgl. 2FA-Flow:
    Ich habe Realm-Rollen angelegt und unter Groups die LML-Rollen mit den Realm-Rollen verknüpft… Habe ich in der Doku scheinbar vergessen. :face_with_peeking_eye:



    Und ja richtig, beim zweiten die Gruppe/Rolle students.

Liebe Grüße
Tobi

Perfekt! Vielen Dank! Hat funktioniert! :heart:

1 „Gefällt mir“

Hallo zusammen,

ich habe am Wochenende meine schlimme Webdesign-Allergie unterdrückt und ein (für mich akzeptables) Keycloak-Theme erzeugt:

Einfachen Keycloak-Login-Theme erstellen

theme-Verzeichnis in Docker-Container einbinden

In das oben schon abgedruckte docker-compose.yaml ein Docker Volume oder einen Bind mount einbinden. Ich mag ja Bind mounts (lokales Verzeichnis z.B. unterhalb des docker-compose.yaml), so lang das mit den Rechten funktioniert, da ich dann mit dem Sichern des Verzeichnisses (bei mir immer /opt/Systemname alles habe. Die „reine Lehre“ sind wohl eher Docker Volumes.

  • Verzeichnis data/themes anlegen (bei mir /opt/keycloak/data/themes): mkdir -p /opt/keycloak/data/themes
  • Owner richtig setzten (der keycloak-Owner im Docker hat die User-ID 1000): cd /opt/keycloak/data && chown 1000 themes
  • docker-compose.yaml ändern und folgende Zeilen in die Sektion keycloak_web einfügen:
    volumes:
      - ./data/themes:/opt/keycloak/themes

Wer lieber ein echtes Docker Volume hat: docker volume create keycloak_data. Dann sieht die Zeile in der docker-compose.yaml so aus:

    volumes:
      - keycloak_data:/opt/keycloak/themes

Beschreibung im Weiteren aber für den Bind mount.

Apropos docker-compose.yaml: wer am Theme „rumbasteln“ möchte, ändert in der Datei das Startkommando von command: start in command: start-dev. Damit ist dann u.a. auch das Caching abgeschaltet, so dass man auch sofort sieht, was man geändert hat.

theme-Verzeichnis anlegen

Unterhalb des neuen theme-Verzeichnisses (/opt/keycloak/data/themes) müsst ihr jetzt folgende Dateien erstellen/ablegen:

<themeName>
  + login
    + theme.properties
    + resources
      + css
        + styles.css
      + img
        + background.jpg
    + messages
      + messages_de.properties

Ein hübsches backgroud.jpg ablegen (oder eines erstellen). Hier der Inhalt meiner anderen Dateien:

theme.properties:

parent=keycloak
import=common/keycloak
styles=css/login.css css/styles.css

styles.css

#kc-login {
    background-color: var(--pf-global--palette--green-600);
}

#kc-login:hover {
    background-color: var(--pf-global--palette--green-700);
}

.login-pf body {
  background: url("../img/background.jpg") no-repeat center center fixed;
  background-size: cover;
}

#kc-header-wrapper {
  padding: 0px 0px 0px 0px;
}

.card-pf {
  border-color: #307924;
  border-top-left-radius: 30px;
  border-top-right-radius: 30px;
  border-bottom-left-radius: 30px;
  border-bottom-right-radius: 30px;
}

.login-pf-page .login-pf-page-header {
  margin-bottom: 20px;
}

Nagelt mich nicht an die Wand: ich bin kein Webdesigner und bin da auch untalentiert. Bin aber für hübschere Design-Vorschläge sofort zu haben! Ich habe einfach so lang „rumgeschraubt“, bis ich das Ergebnis ohne Tränen in den Augen anschauen konnte.

Das Verzeichnis messages ist optional. Hier kann man in der Datei messages_<SprachCode>.properties Texte überschreiben. Welche es gibt, kann man ganz gut hier nachschauen. Meine messages_de.properties:

loginAccountTitle=Willkommen beim TGSlogin
usernameOrEmail=Benutzername
loginTitleHtml=
totpAppGoogleName=
totpAppMicrosoftAuthenticatorName=

Mit letzteren beiden Zeilen blendet man die Werbung für den Google & Microsoft Authenticator bei der 2FA-Einrichtung aus (es verbleibt der Verweis auf FreeOTP).

Theme aktivieren

Wenn alles geklappt hat, solltet ihr jetzt in der Keycloak-Admin-Oberfläche unter Eurem Realm > Realm-Einstellungen > Theme > Theme für Anmeldung einen weiteren Theme gem. dem Namen Eures Theme-Verzeichnisses auswählen und speichern können.

Viel Spaß!
Jens

1 „Gefällt mir“

muss resources heißen :melting_face:
ansonsten hat es geklappt, vielen Dank! :partying_face:

Bin da jetzt auch nicht so affine… habe nur noch das Schullogo über den Willkommenstext ergänzt und bin damit erstmal sehr glücklich… :blush:

/* Stile für das Logo neben dem Feedback-Text */
#kc-page-title::before {
    content: '';
    display: block;
    background-image: url('../img/logo.png'); /* Pfad zu Ihrem Logo */
    background-size: contain; /* Hintergrundbild skalieren, um den Container zu füllen */
    background-repeat: no-repeat; /* Hintergrundbild nicht wiederholen */
    width: 350px; /* Breite des Logos anpassen */
    height: 200px; /* Höhe des Logos anpassen */
    margin: 0 auto 30px auto; /* Zentrieren und Abstand nach unten */
}

Danke! Korrigiert!