In der migrations.rake
(wget -P lib/tasks/migrations https://raw.githubusercontent.com/bigbluebutton/greenlight/v2/lib/tasks/migrations/migrations.rake) in der Task der user Migration an der folgenden Stelle :social_id
gegen :username
austauschen:
User.unscoped
.select(:id, :uid, :name, :email, :username, :language, :role_id)
.includes(:role)
.where.not(roles: { name: COMMON[:filtered_user_roles] }, deleted: true)
.find_each(start: start, finish: stop, batch_size: COMMON[:batch_size]) do |u|
role_name = infer_role_name(u.role.name)
params = { user: { name: u.name, email: u.email, external_id: u.username, language: u.language, role: role_name } }
https://doku.tid.dfn.de/de:shibidp:config-extensions-oidc
Offene Registrierung muss angeschaltet sein, sonst müssen die Nutzer noch freigegeben werden
https://docs.bigbluebutton.org/greenlight/v3/migration/
https://docs.bigbluebutton.org/greenlight/v3/external-authentication/
https://github.com/bigbluebutton/greenlight/pull/5107
https://github.com/bigbluebutton/greenlight-run
https://github.com/bigbluebutton/greenlight/blob/master/docker-compose.yml
A Federated OpenID Connect Provider
https://dexidp.io/
Authentication Through LDAP
https://dexidp.io/docs/connectors/ldap/
authentik
https://goauthentik.io/
und eine Art Anleitung für authentik
https://github.com/bigbluebutton/greenlight/issues/4817#issuecomment-1501157949
https://github.com/bigbluebutton/greenlight/issues/5062
https://groups.google.com/g/bigbluebutton-greenlight/c/gx1Q6Ic96HY/m/bd2dqFhKAQAJ
Aktuell funktioniert der Betrieb unter einem URL-Prefix nicht.
https://github.com/bigbluebutton/greenlight/issues/5176
ein Projekt hat dies für v2.x mal versucht (PoC): https://github.com/oxzi/greenlight-ldap-sync
Eine funktionierende Config für Greenlight mit LDAP via Dex. Details unter Dex: Authentication Through LDAP. Hier wird alles per docker-compose auf einem gemeinsamen Host betrieben, dabei nutze ich aus, dass die Container untereinander direkt kommunizieren können und verwende URLs wie http://greenlightv3:3000
, http://dex:5556
oder den Docker-Compose container_name
um z.B. auf die Postgres-DB zuzugreifen.
Die Datenbank für Dex muss im Vorfeld manuell generiert werden, dazu die Postgres-Commandline aufrufen
docker exec -it root_db14_1 psql -U postgres
Und darin dann die DB erstellen - ob der grant
wirklich nötig ist, oder ob postgres
sowieso dürfte, hab ich nicht nachgeschaut…
create database dex_db
grant all privileges on database dex_db to postgres;
Wenn man nicht den für Greenlight ohnehin vorhandenen Postgres-Docker mitnutzen möchte, gibts hier noch andere Möglichkeiten:
https://dexidp.io/docs/storage/
Wichtig: wenn man bisherige "External IDs" migrieren will, muss sie in einem Dex-spezifischen Format (Protobuf) angelegt werden:
message IDTokenSubject {
string user_id = 1;
string conn_id = 2;
}
Ich habe das erst nachträglich in der Datenbank getan, indem ich den Base64-Kodierten Bytestream selbst zusammengebaut habe, was glücklicherweise halbwegs überschaubar war, solange der Inhalt des im Dex konfigurierten "idAttr"s immer < 127 Zeichen lang ist. Für größere Attributlängen (z.B. Tiefe OU-Strukturen im LDAP) müsste man sich noch mit dem Protobuf-VarInt-Datentyp auseinandersetzen. Nützlich war auch ein Javascript-basierendes Online-Decoder-Tool.
update users set external_id=rtrim(encode((chr(10)||chr(length(external_id))|| external_id ||chr(18)||chr(4)||'ldap')::bytea,'base64'),'=');
Eventuell lässt sich das aber auch gleich in der Ruby-Migrationsroutine mit erledigen…
issuer: https://<external_url>/dex
storage:
type: postgres
config:
host: <docker service name>
port: 5432
database: dex_db
user: postgres
password: <use same PW as for Greenlight?>
ssl:
mode: disable #Local connection only
web:
http: 0.0.0.0:5556
oauth2:
skipApprovalScreen: true #Sonst wird bei jedem Login gefragt, ob Greenlight auf Name und Email-Adresse zugreifen darf...
connectors:
- type: ldap
name: OpenLDAP
id: ldap
config:
# The following configurations seem to work with OpenLDAP:
#
# 3) LDAPS with certificate validation:
host: <LDAP HOST>:636
insecureNoSSL: false
insecureSkipVerify: false
#rootCAData: 'CERT'
# ...where CERT="$( base64 -w 0 your-cert.pem )"
# alternatively mount /etc/ssl/certs/ca-certificates.crt into the container and point to it with
# rootCA: /etc/dex/ldap.ca
# This would normally be a read-only user.
bindDN: <...>
bindPW: <...>
# i18n!
usernamePrompt: Benutzerkennung
userSearch:
baseDN: ou=people,dc=example,dc=com
filter: "(&(objectClass=person))"
username: uid
# "DN" (case sensitive) is a special attribute name. It indicates that
# this value should be taken from the entity's DN not an attribute on
# the entity.
idAttr: uid
emailAttr: mail
nameAttr: cn
# groupSearch:
# baseDN: ou=Groups,dc=example,dc=org
# filter: "(objectClass=groupOfNames)"
#
# userMatchers:
# # A user is a member of a group when their DN matches
# # the value of a "member" attribute on the group entity.
# - userAttr: DN
# groupAttr: member
#
# # The group name should be the "cn" value.
# nameAttr: cn
staticClients:
- id: greenlight-v3
redirectURIs:
- 'https://<Greenlight external URL>/auth/openid_connect/callback'
name: 'Greenlight v3'
secret: <Same as in GLv3 env>
#...
### EXTERNAL AUTHENTICATION METHODS
#
# Same as in Dex-Config:
OPENID_CONNECT_CLIENT_ID=greenlight-v3
OPENID_CONNECT_CLIENT_SECRET=<same as in Dex Config>
OPENID_CONNECT_ISSUER=https://<external_url>/dex
OPENID_CONNECT_REDIRECT=https://<Greenlight eternal URL>
#...
dex:
image: dexidp/dex:v2.37.0
container_name: dex
volumes:
- /opt/dex/config-ldap.yaml:/etc/dex/config.docker.yaml
# perhaps use host's CA-Certificates
# - /etc/ssl/certs/ca-certificates.crt:/etc/dex/ldap.ca
Da es nicht so leicht ist, eine nginx-Config als Dex-Reverse Proxy zu finden, hab ich eine für Greenlight v3 kopiert und angepasst. Mag sein, dass im folgenden das eine oder andere Setting zu viel ist, geschadet hat es aber nicht:
location /dex {
proxy_pass http://dex:5556;
proxy_read_timeout 60s;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie "$http_cookie; ip=$remote_addr";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_headers_hash_max_size 512;
proxy_headers_hash_bucket_size 128;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
client_max_body_size 30m;
}