Server bbb
Zum 16.05.2024 wird der BBB-Server abgeschaltet.
Date: Wed, 17 Apr 2024 21:05:06 +0200 From: Alvar Penning <REDACTED> To: public@lists.hsmr.cc Subject: Abschaltung BigBlueButton Hej Liste, zum 16.05. wird der BigBlueButton-Server bbb.hsmr.cc abgeschaltet. Dieser wurde vor nun knapp drei Jahren im Mai 2021 aufgrund des damaligen Bedarfs in Betrieb genommen und lief seitdem mit kurzen Updatepausen durch. Gründe für die Abschaltung gibt es zwei (oder drei): 1. Glücklicherweise hat sich seit der Anschaffung die Gesamtsituation verändert und somit wurde der Server im letzten Jahr nicht verwendet. 2. Der Software-Stack ist etwas in die Jahre gekommen. Das Webfrontend greenlight hat einen Major-Versionssprung genommen und dabei leider den für uns notwendigen LDAP-Support unter die Räder kommen lassen[0]. Ohne LDAP ist die greenlight in der Hackspace-Infra aber weitgehend wertlos. 3. Der Server kostete Geld, welches jedoch bei Nichtbenutzung verschwendet wirkte. Falls jemand das Projekt übernehmen mag, gibt es die Doku im Wiki[1] und natürlich bin ich für Rückfragen auch erreichbar. Viele Grüße Alvar [0] https://github.com/bigbluebutton/greenlight/issues/4817 [1] https://hsmr.cc/Infrastruktur/ServerBbb
Öffentlicher Raum unter https://bbb.hsmr.cc/b/general.
Netzwerk | |
---|---|
IPv4 | 202.61.230.59/32 |
IPv6 | 2a03:4000:57:cf5::2/64 |
Hostname | bbb.hsmr.cc |
Der Hackspace betreibt eine BigBlueButton-Instanz zum gemeinsamen Schnaken, Planen oder gar für Vorträge. Diese ist unter https://bbb.hsmr.cc/ zu erreichen.
Einloggen lässt sich dort via LDAP-Account, welcher sonst fürs Zammad genutzt wird. Mittels Account lassen sich neue Sitzungen erstellen. Beitreten ist ohne Account möglich bzw. durch die sitzungsspezifischen Einstellungen geregelt.
Ein gemeinsamer öffentlicher Raum ist unter https://bbb.hsmr.cc/b/general zu erreichen.
Die Installation ist noch recht frisch, also bitte mit Vorsicht testen und Fehler oder Verbesserungsvorschläge zeitig kommunizieren.
Bei der Installation wurde auf Datensparsamkeit geachtet, jedoch besteht ein BBB aus verschiedenen Services. Wir versuchen durch regelmäßiges Prüfen sicherzustellen, dass keine personenbezogenen Daten langfristig gespeichert werden.
Alle Sitzungen, bei denen eine Aufname möglich ist, werden kurzzeitig auf Platte geschrieben. Dies sollte vorm Joinen durch eine extra Abfrage und während der Sitzung durch die "Recording-LED" oben in der Mitte angezeigt werden.
On this page... (hide)
- 1. Installation/Konfiguration
- 1.1 Basis
- 1.2 Docker
- 1.3 Greenlight
- 1.4 Greenlight LDAP-Sync
- 1.5 BigBlueButton
- 1.6 TURN-Server
- 1.7 Privacy / Logging
- 1.8 Prometheus Exporter
- 1.9 Restic Backups
- 2. Maintenance
1. Installation/Konfiguration
1.1 Basis
Die Basisinstallation ist analog zur Dokumentation. Deswegen ist das OS auch ein Ubuntu 18.04, basierend auf dem "Minimal" Image.
Vor der eigentlichen BBB-Installation wurden folgende stichpunktartige Schritte vorgenommen:
visudo
:NOPASSWD
für%sudo
gesetzt.- Neuen User in der
sudo
-Gruppe angelegt. /etc/ssh/sshd_config
: Pubkey-only-Authentication/etc/netplan/50-cloud-init.yaml
anpassen, anschließendnetplan apply
hostnamectl set-hostname bbb.hsmr.cc
- Docker installiert, Docker-Dokumentation
Nun wurde die eigentliche BBB-Installation via bbb-install.sh
durchgeführt.
$ wget https://ubuntu.bigbluebutton.org/bbb-install.sh $ chmod +x bbb-install.sh $ sudo ./bbb-install.sh -v bionic-23 -s bbb.hsmr.cc -e XXX -g -w
User
Zugang haben aktuell: oxzi (alvar
), xkey (xkey
)
Neue User werden lassen sich folgendermaßen anlegen:
$ sudo useradd -g users -G sudo -m -N $USERNAME
Da ein SSH-Login ausschließlich via Public Key erlaubt ist, muss dieser entsprechend abgelegt werden:
$ echo $KEY > ~/.ssh/authorized_keys $ chmod 600 ~/.ssh/authorized_keys
1.2 Docker
Per default spricht Docker nur legacy IP. Da wir gerne via IPv6 mit dem LDAP-Server kommunizieren würde, müssen wir dies anpassen.
Für die Docker-Container erlauben wir ein Subnetz von unserem /64er, hier das hintere /65er. Anschließend konfigurieren wir den NDP Proxy Daemon.
Unabhängig davon konfigurieren wir, dass Docker generell nach journald loggt. Somit haben wir später nicht die Logs an tausend Orten.
$ cat /etc/docker/daemon.json { "ipv6": true, "fixed-cidr-v6": "2a03:4000:57:cf5:8000::/65", "log-driver": "journald" } $ tail -n 1 /etc/sysctl.conf net.ipv6.conf.eth0.proxy_ndp=1 $ sudo sysctl -p /etc/sysctl.conf $ sudo apt-get install ndppd $ cat /etc/ndppd.conf proxy eth0 { rule 2a03:4000:57:cf5:8000::/65 { auto } } $ sudo systemctl restart ndppd.service
1.3 Greenlight
Greenlight ist ein Web-Frontend sowohl für die User-Authentifizierung wie auch die Erstellung von Räumen.
Im Produktivbetrieb wickeln wir dies über unser LDAP ab. Zum Debuggen gibt es einen lokalen Admin, dessen Zugang entsprechend aktiviert werden muss.
Die Greenlight-Installation liegt in /opt/greenlight
.
Docker Compose
Um Docker mit IPv6 zu nutzen, wurde in der docker-compose.yml
beiden Services der network_mode: bridge
hinzugefügt.
Ferner sollen die Container ins Journal loggen.
Zusammen sieht die docker-compose.yml
wie folgt aus:
version: '3' services: app: entrypoint: [bin/start] image: bigbluebutton/greenlight:v2 container_name: greenlight-v2 env_file: .env restart: unless-stopped ports: - 127.0.0.1:5000:80 # When using external logging # logging: # driver: $LOG_DRIVER # options: # syslog-address: $LOG_ADDRESS # tag: $LOG_TAG volumes: - ./log:/usr/src/app/log - ./storage:/usr/src/app/storage # When using sqlite3 as the database # - ./db/production:/usr/src/app/db/production # When using postgresql as the database links: - db network_mode: bridge logging: driver: "journald" db: image: postgres:13.2-alpine restart: unless-stopped ports: - 127.0.0.1:5432:5432 volumes: - ./db/production:/var/lib/postgresql/data environment: - POSTGRES_DB=postgres - POSTGRES_USER=postgres - POSTGRES_PASSWORD=XXX network_mode: bridge logging: driver: "journald"
Greenlight Config
Die Konfiguration erfolgt über die .env
-Datei.
Angepasst wurde hier lediglich der LDAP-Abschnitt.
LDAP_SERVER=ldap.hsmr.cc LDAP_PORT=636 LDAP_METHOD=ssl LDAP_UID=uid LDAP_BASE=dc=hsmr,dc=cc LDAP_BIND_DN=cn=bbb,dc=hsmr,dc=cc LDAP_AUTH=simple LDAP_PASSWORD=XXX LDAP_ROLE_FIELD= LDAP_FILTER= LDAP_ATTRIBUTE_MAPPING=name=displayName;uid=uid;
Systemd Unit
Gestartet wird Greenlight via systemd, /etc/systemd/system/greenlight.service
:
[Unit] Description=Greenlight Requires=docker.service [Service] Type=oneshot RemainAfterExit=true WorkingDirectory=/opt/greenlight ExecStart=/usr/local/bin/docker-compose up -d --remove-orphans --build ExecStop=/usr/local/bin/docker-compose down [Install] WantedBy=multi-user.target
Lokaler Admin-Account
Weiter wurde ein lokaler Administrator angelegt; siehe Dokumentation.
Dessen Login-Credentials stehen in /root/greenlight-admin
.
Standardmäßig ist dieser Account nicht nutzbar, da in der Greenlight-Konfiguration
ALLOW_GREENLIGHT_ACCOUNTS=false
gesetzt ist. Falls also der Admin benötigt wird, müssen kurzzeitig (!) lokale Accounts erlaubt werden. Hierzu ist jeweils ein Neustart von Greenlight notwendig.
Einfacher ist es kurzfristig die Rechte eines LDAP-Users zu erhöhen, siehe unten.
1.4 Greenlight LDAP-Sync
Aktuell synchronisiert Greenlight User-Daten beim ersten Login vom LDAP in die eigene PostgreSQL-Datenbank. Spätere LDAP-Syncs werden nicht durchgeführt, siehe Issue #1918.
Als Behilfslösung schrieb ich dafür greenlight-ldap-sync
.
$ cd /opt/greenlight $ git clone https://github.com/oxzi/greenlight-ldap-sync.git
Die docker-compose.yml
wurde um folgenden service
erweitert:
ldap-sync: build: context: ./greenlight-ldap-sync env_file: .env environment: # - SYNC_DEBUG=on - SYNC_INTERVAL=30m restart: unless-stopped links: - db network_mode: bridge logging: driver: "journald"
1.5 BigBlueButton
Zum Verwalten der Dienste nutzt BBB natürlich nicht systemd, sondern eigene Skripte.
Besonders relevant sind hier bbb-conf
und bbb-record
.
Zum Starten/Stoppen/Prüfen gibt es:
sudo bbb-conf --{start,stop,status}
Aufnahmen lassen sich mit
bbb-record --list
anzeigen und auch löschen, siehe --help
.
Allgemein hat BBB nach der Installation relative sinnvolle Defaults, trotzdem ein paar Anpassungen.
Ungewollte Recordings aufräumen
BBB zeichnet alle Sitzungen auf, wo ein Recording möglich ist (!). Es muss also nicht in der Web-UI die Aufnahme gestartet worden sein, sondern es genügt, dass der Aufnahme-Button möglich ist.
Es gibt einen Cronjob in /etc/cron.daily/bigbluebutton
, welcher ältere Dateien löscht, siehe Dokumentation.
history=1 unrecorded_days=1 published_days=1 log_history=1
All diese Variablen werden als -mtime +${VAR}
an find
übergeben.
Somit werden Dateien welche nach über 1*24h bearbeitet wurden gelöscht, was zwei Tagen entspricht.
Drei parallele Kurento-Instanzen
Die Dokumentation sagt, dass drei Kurento-Instanzen - je eine für "listen only, webcams, and screen share" - besser performen.
Also wurde zu /etc/bigbluebutton/bbb-conf/apply-config.sh
folgender Eintrag hinzugefügt:
enableMultipleKurentos
Echo Test deaktivieren
Standardmäßig wird beim Joinen mit Mikrofon ein Test durchgeführt, welcher jedoch meistens nur nervt.
Deswegen in /usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml
den Eintrag public.app.skipCheck
auf true
setzen.
sudo sed -i.bak 's/\([ ]*skipCheck\): .*$/\1: true/g' /usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml
HSMR-Favicon
Das Favicon lässt sich austauschen, z.B. zum [hsmr]™-Branding.
$ cd /var/www/bigbluebutton-default/ $ rm favicon.ico $ wget -O favicon.ico https://hsmr.cc/favicon.ico
Damit Greenlight dieses auch ausliefert, müssen wir es in der docker-compose.yml
dazu überreden, indem wir den Default übermounten.
services: app: volumes: - /var/www/bigbluebutton-default/favicon.ico:/usr/src/app/app/assets/images/favicon.ico
1.6 TURN-Server
Standardmäßig verwendet BBB die TURN/STUN-Server von Google. Aus Gründen setzen wir auf unserem Server lieber einen eigenen auf.
Das tolle bbb-install.sh
-Script kann dies theoretisch, jedoch nur für Ubuntu 20.04 und nicht für 18.04, welches angeblich verpflichtend sei…
Die folgenden Schritte orientieren sich stark an der BBB-Anleitung.
Initial installieren und konfigurieren wir coturn.
$ sudo apt-get install coturn $ grep "^[^#]" /etc/default/coturn TURNSERVER_ENABLED=1 $ sudo mkdir /etc/turnserver/ $ sudo chown turnserver:turnserver /etc/turnserver $ sudo chmod 700 /etc/turnserver $ cat /etc/letsencrypt/renewal-hooks/deploy/coturn #!/bin/bash -e for certfile in fullchain.pem privkey.pem ; do cp -L /etc/letsencrypt/live/bbb.hsmr.cc/"${certfile}" /etc/turnserver/"${certfile}".new chown turnserver:turnserver /etc/turnserver/"${certfile}".new mv /etc/turnserver/"${certfile}".new /etc/turnserver/"${certfile}" done systemctl kill -sUSR2 coturn.service $ sudo chmod 755 /etc/letsencrypt/renewal-hooks/deploy/coturn $ sudo /etc/letsencrypt/renewal-hooks/deploy/coturn $ sudo openssl dhparam -dsaparam -out /etc/turnserver/dhp.pem 2048 $ sudo chown turnserver:turnserver /etc/turnserver/dhp.pem $ grep "^[^#]" /etc/turnserver.conf listening-port=3478 tls-listening-port=5349 listening-ip=202.61.230.59 listening-ip=2a03:4000:57:cf5::2 relay-ip=202.61.230.59 relay-ip=2a03:4000:57:cf5::2 min-port=49152 max-port=65535 fingerprint lt-cred-mech use-auth-secret static-auth-secret=XXX realm=bbb.hsmr.cc cert=/etc/turnserver/fullchain.pem pkey=/etc/turnserver/privkey.pem dh-file=/etc/turnserver/dhp.pem no-loopback-peers no-multicast-peers denied-peer-ip=0.0.0.0-0.255.255.255 denied-peer-ip=127.0.0.0-127.255.255.255 denied-peer-ip=::1 denied-peer-ip=10.0.0.0-10.255.255.255 denied-peer-ip=172.16.0.0-172.31.255.255 denied-peer-ip=192.168.0.0-192.168.255.255 denied-peer-ip=100.64.0.0-100.127.255.255 denied-peer-ip=169.254.0.0-169.254.255.255 denied-peer-ip=192.0.0.0-192.0.0.255 denied-peer-ip=192.0.2.0-192.0.2.255 denied-peer-ip=198.18.0.0-198.19.255.255 denied-peer-ip=198.51.100.0-198.51.100.255 denied-peer-ip=203.0.113.0-203.0.113.255 denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff denied-peer-ip=::ffff:0:0-::ffff:ffff:ffff denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff denied-peer-ip=64:ff9b:1::-64:ff9b:1:ffff:ffff:ffff:ffff:ffff denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff denied-peer-ip=2001:db8::-2001:db8:ffff:ffff:ffff:ffff:ffff:ffff denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff no-cli no-tlsv1 no-tlsv1_1
In /etc/bigbluebutton/bbb-conf/apply-config.sh
fügen wir die zusätzlich benötigten Firewall-Regeln vor enableUFWRules
hinzu.
ufw allow 3478/tcp ufw allow 3478/udp ufw allow 5349/tcp ufw allow 5349/udp ufw allow 49152:65535/udp
Abschließend teilen wir noch BBB mit unseren eigenen Server zu nutzen; /usr/share/bbb-web/WEB-INF/classes/spring/turn-stun-servers.xml
:
<?xml version="1.0" encoding="UTF-8"?> <!-- BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3.0 of the License, or (at your option) any later version. BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd "> <bean id="stun1" class="org.bigbluebutton.web.services.turn.StunServer"> <constructor-arg index="0" value="stun:bbb.hsmr.cc"/> </bean> <bean id="turn1" class="org.bigbluebutton.web.services.turn.TurnServer"> <constructor-arg index="0" value="XXX"/> <!-- static-auth-secret hier --> <constructor-arg index="1" value="turns:bbb.hsmr.cc:5349?transport=tcp"/> <constructor-arg index="2" value="86400"/> </bean> <bean id="turn2" class="org.bigbluebutton.web.services.turn.TurnServer"> <constructor-arg index="0" value="XXX"/> <constructor-arg index="1" value="turn:bbb.hsmr.cc:5349?transport=tcp"/> <constructor-arg index="2" value="86400"/> </bean> <bean id="stunTurnService" class="org.bigbluebutton.web.services.turn.StunTurnService"> <property name="stunServers"> <set> <ref bean="stun1" /> </set> </property> <property name="turnServers"> <set> <ref bean="turn1" /> <ref bean="turn2" /> </set> </property> <property name="remoteIceCandidates"> <set> </set> </property> </bean> </beans>
Nach einem Neustart von BBB sollte der TURN-Server genutzt werden. Dies lässt sich testen, wie upstream bei BBB dokumentiert.
1.7 Privacy / Logging
Wunschzustand ist, dass Logs entweder gar nicht, anonymisiert oder nur kurzlebig existieren. Da BBB selbst aus drölfzig Services besteht, muss an einigen Stellen Hand angelgt werden.
Dieser Abschnitt sollte nach gewisser Zeit evaluiert und ggf. angepasst werden.
Systemd Journal
$ grep "^[^#]" /etc/systemd/journald.conf [Journal] SystemMaxUse=50M MaxRetentionSec=1day MaxFileSec=1day ForwardToSyslog=no
UFW
Per default ist UFW arg verbose bzgl. geblockten Verbindungen. Da sich dies sowieso niemand ansieht, kann es auch weg.
$ tail -n1 /etc/bigbluebutton/bbb-conf/apply-config.sh ufw logging off
Docker
Wurde bereits oben durch {"log-driver": "journald"}
nach Journald umgelenkt.
Nginx
Die Log-Konfiguration sollte allein in /etc/nginx/nginx.conf
geschehen.
Hier werden keine Access Logs erstellt und Error Logs ans Journal übergeben, sodass Systemd Journald sie wegrotiert.
http { access_log off; error_log stderr error; }
BigBlueButton
In /usr/share/bbb-web/WEB-INF/classes/logback.xml
definiert BBB ein eignes logrotate für Logs in /var/log/bigbluebutton/bbb-web.YYYY-MM-DD.log
.
Hier also den Wert für MaxHistory
auf 1 setzen.
sed -i.bak 's/\([ ]*\<MaxHistory>\)[0-9]*\(.*\)$/\11\2/g' /usr/share/bbb-web/WEB-INF/classes/logback.xml
Freeswitch
Freeswitch loggt ebenfalls fleißig, wobei der Backlog abermals via XML reduziert werden kann.
In /etc/bbb-fsesl-akka/logback.xml
abermals die MaxHistory
auf 1 reduzieren.
sed -i.bak 's/\([ ]*\<MaxHistory>\)[0-9]*\(.*\)$/\11\2/g' /etc/bbb-fsesl-akka/logback.xml
logrotate
Zusätzlich nutzt BBB auch das normale logrotate.
Hier gibt es /etc/logrotate.d/bbb-{record-core,webrtc-sfu}.logrotate
, welche wir aber entfernen.
Anschließend legen wir eine gemeinsame Config für BBB, Kurento, Coturn und Greenlight anlegen.
- Kurento: Logfiles benannt nach Datum und PID (?) in
/var/log/kurento-media-server
. - Greenlight: Meistens via Docker ins Journal; anderes nach
/opt/greenlight/log/production.log
geschrieben.
$ sudo rm /etc/logrotate.d/bbb-*.logrotate $ cat /etc/logrotate.d/bbb-meta /var/log/bigbluebutton/bbb-rap-worker.log /var/log/bigbluebutton/sanity.log /var/log/bbb-webrtc-sfu/*.log /var/log/kurento-media-server/*.log /var/log/turn_*.log /opt/greenlight/log/production.log { copytruncate missingok notifempty daily rotate 1 maxage 1 }
1.8 Prometheus Exporter
Es werden zwei Prometheus Exporter installiert. Einmal den BigBlueButton Exporter speziell für BBB. Zusätzlich noch den Node Exporter für generelle Systeminformationen.
$ mkdir /opt/bbb-exporter $ cd /opt/bbb-exporter $ cat docker-compose.yaml version: '3' services: bbb-exporter: container_name: bbb-exporter image: greenstatic/bigbluebutton-exporter:v0.6.0 ports: - "127.0.0.1:9688:9688" volumes: - "/var/bigbluebutton:/var/bigbluebutton:ro" environment: RECORDINGS_METRICS_READ_FROM_DISK: "true" env_file: - secrets.env restart: unless-stopped node_exporter: container_name: node_exporter image: quay.io/prometheus/node-exporter:latest command: - '--path.rootfs=/host' - "--web.listen-address=127.0.0.1:9100" network_mode: host pid: host restart: unless-stopped volumes: - '/:/host:ro,rslave' restart: unless-stopped $ bbb-conf --secret # -> API_BASE_URL wird URL mit api/-Endpunkt # -> API_SECRET wird Secret $ cat secrets.env API_BASE_URL=https://bbb.hsmr.cc/bigbluebutton/api/ API_SECRET=XXX # Öffentlich erreichbar wird der Service geproxied via nginx $ apt-get install apache2-utils $ htpasswd -c htpasswd metrics # nginx mag kein bcrypt, sagt es aber nicht direkt… $ chgrp www-data htpasswd $ chmod 440 htpasswd $ cat /etc/bigbluebutton/nginx/monitoring.nginx location /metrics_node/ { auth_basic "Node Exporter"; auth_basic_user_file /opt/bbb-exporter/htpasswd; proxy_pass http://127.0.0.1:9100/; include proxy_params; } location /metrics_bbb/ { auth_basic "BigBlueButton Exporter"; auth_basic_user_file /opt/bbb-exporter/htpasswd; proxy_pass http://127.0.0.1:9688/; include proxy_params; } $ systemctl reload nginx # Und jetzt noch den Container automatisch starten $ cat /etc/systemd/system/bbb-exporter.service [Unit] Description=BBB Exporter Requires=docker.service [Service] Type=oneshot RemainAfterExit=true WorkingDirectory=/opt/bbb-exporter ExecStart=/usr/local/bin/docker-compose up -d --remove-orphans --build ExecStop=/usr/local/bin/docker-compose down [Install] WantedBy=multi-user.target $ systemctl daemon-reload $ systemctl enable bbb-exporter.service $ systemctl start bbb-exporter.service
Auf ancha läuft ein Prometheus, welcher die Metrics abfragt. Dieses ist in der NixOS-Konfiguraiton folgendermaßen definiert.
{ services.prometheus = { enable = true; scrapeConfigs = [ # . . . { job_name = "bbb"; basic_auth = { username = "metrics"; password = "XXX"; }; scheme = "https"; metrics_path = "/metrics_node/metrics"; static_configs = [{ targets = [ "bbb.hsmr.cc" ]; }]; } { job_name = "bbb-exporter"; basic_auth = { username = "metrics"; password = "XXX"; }; scheme = "https"; metrics_path = "/metrics_bbb/metrics"; static_configs = [{ targets = [ "bbb.hsmr.cc" ]; }]; } ]; # . . . }; }
1.9 Restic Backups
Konfigurationseinträge und ähnliches werden mit restic auf den restic Rest Server auf ancha gesichert.
Da es mit den Paketen für ein LTS-Ubuntu traurig aussieht, wird das statische Binary von GitHub installiert.
$ wget https://github.com/restic/restic/releases/download/v0.12.0/restic_0.12.0_linux_amd64.bz2 $ bunzip2 restic_0.12.0_linux_amd64.bz2 $ install -m 755 restic_0.12.0_linux_amd64 /usr/bin/restic
Das Repository muss eingangs initialisiert werden. Die Credentials liegen u.a. für den root-User in dessen Home-Verzeichnis.
$ ls -l /root/restic-* -r-------- 1 root root 33 Jun 6 12:59 /root/restic-pw -r-------- 1 root root 33 Jun 6 12:59 /root/restic-rest $ restic init -r rest:https://bbb:XXX@ancha.lurk.space/restic/bbb/
Angestoßen werden die Backups dann über systemd.
$ cat /root/restic-include /etc/bigbluebutton/ /etc/cron.* /etc/default/coturn /etc/docker/*.json /etc/logrotate.d/ /etc/nginx/ /etc/systemd/journald.conf /home/ /opt/bbb-exporter /opt/greenlight/ /root/ /usr/share/bbb-web/WEB-INF/classes/spring/turn-stun-servers.xml /usr/share/meteor/bundle/programs/server/assets/app/config/ $ cat /root/restic-exclude /home/*/.cache /opt/greenlight/log/ $ systemctl cat restic-backup.service # /etc/systemd/system/restic-backup.service [Unit] Description=restic backup [Service] Environment="HOME=/root" Environment="RESTIC_PASSWORD_FILE=/root/restic-pw" Environment="RESTIC_REPOSITORY=rest:https://bbb:XXX@ancha.lurk.space/restic/bbb/" Type=oneshot ExecStart=/usr/bin/restic backup --files-from /root/restic-include --exclude-file /root/restic-exclude $ systemctl cat restic-backup.timer # /etc/systemd/system/restic-backup.timer [Unit] Description=scheduled restic backup [Timer] OnCalendar=daily Unit=restic-backup.service [Install] WantedBy=timers.target $ systemctl enable --now restic-backup.timer
2. Maintenance
2.1 BBB, Updates und After Care
Nach einem Upgrade von BBB-Paketen (prefixed mit bbb-
) via apt-get
muss Folgendes durchgeführt werden.
- BBB neustarten:
sudo bbb-conf --restart
- Falls hier Probleme gelistet werden, müssen diese händisch behoben werden.
Glücklicherweise ist die Problembeschreibung recht gut und BBB's Issue Tracker hilft.
Weiter gibt es nochbbb-conf --check
und--status
. - Folgende Abschnitte wiederholen, zusammengefasst in
/root/bin/post-bbb-update.sh
- BBB für Änderungen neustarten:
sudo bbb-conf --restart
- Greenlight neustarten:
sudo systemctl restart greenlight.service
- Funktionalität im Browser testen!
2.2 Greenlight, Update
Da Greenlight leider via Docker Compose deployed ist, gibt es hier keinen wirklichen Package Manager. Vielmehr wird das aktuelle Image von Docker Hub bezogen, wobei der Tag entsprechend des Releases verwendet wird.
Vor einem Update muss zwingend geprüft werden, ob das Datenbank-Schema geändert wurde. Falls ja, muss die Kompatibilität mit dem LDAP-Sync geprüft und ggf. wiederhergestellt werden.
Der passende Tag lässt sich auf Docker Hub finden. Hierbei sollte die genaue Version entsprechend des Git Tags verwendet werden, z.B. v2.10.0.2.
- In
/opt/greenlight/docker-compose.yml
den Wertservices.app.image
anpassen, z.B. aufbigbluebutton/greenlight:v2.10.0.2
systemctl restart greenlight.service
2.3 Greenlight, Admin werden
Übers Greenlights PostgreSQL lassen sich User ad hoc zum Admin upgraden.
role_id = 1
: Userrole_id = 2
: Admin
alvar@bbb:/opt/greenlight$ sudo docker exec -it greenlight_db_1 bash bash-5.1# psql greenlight_production postgres greenlight_production=# SELECT * FROM users; id | room_id | provider | uid | name | username | email | social_uid | image | password_digest | accepted_terms | created_at | updated_at | email_verified | language | reset_digest | reset_sent_at | activation_digest | activated_at | deleted | role_id | last_login ----+---------+------------+-----------------+---------------+----------+------------------------+------------+-------+--------------------------------------------------------------+----------------+----------------------------+----------------------------+----------------+----------+--------------+---------------+-------------------+--------------+---------+---------+---------------------------- 2 | 2 | ldap | gl-qwertyuiopas | Vor Nachname | username | example@example.org | username | | | f | 2021-05-25 19:53:57.788869 | 2021-05-25 19:54:24.647018 | t | default | | | | | f | 1 | 2021-05-25 19:54:24.646052 greenlight_production=# UPDATE users SET role_id = ROLE_ID WHERE id = ID;
Bitte Rechte nur kurzfristig geben und wieder nehmen.
2.4 Greenlight, Raum-URL anpassen
Die Raum-URL, bzw. speziell der hintere Teil, wird von Greenlight automatisch generiert und kann über die Web-UI nicht angepasst werden.
Auch hier hilft wieder SQL direkt, wobei der Raum-Name in der URL in uid
steht.
alvar@bbb:/opt/greenlight$ sudo docker exec -it greenlight_db_1 bash bash-5.1# psql greenlight_production postgres greenlight_production=# SELECT * FROM rooms; id | user_id | name | uid | bbb_id | sessions | last_session | created_at | updated_at | room_settings | moderator_pw | attendee_pw | access_code | deleted | moderator_access_code ----+---------+----------------------------+-----------------+------------------------------------------+----------+-------------------------+----------------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------+--------------+--------------+-------------+---------+----------------------- 11 | 2 | Water Cooler Conversations | uwu-123-abc-lel | qwertyuiopasdfghjklzxcvbnm1234567890qwer | 0 | | 2021-06-12 08:52:14.786665 | 2021-06-12 08:52:14.786665 | {"muteOnStart":false,"requireModeratorApproval":false,"anyoneCanStart":true,"joinModerator":false,"recording":false} | qwertyuiopas | asdfghjklzxc | | f | greenlight_production=# UPDATE rooms SET uid = 'general' WHERE id = 11;
2.5 Greenlight, Raum mit Access Code sperren
Zugangsberechtigungen lassen sich auch live während Meetings setzen. Die Web-UI erlaubt - wieso auch immer - nur gewürfelte Zahlencodes, was für Verabredungen im Vorfeld schwer fällt. SQL to the rescue.
alvar@bbb:/opt/greenlight$ sudo docker exec -it greenlight_db_1 bash bash-5.1# psql greenlight_production postgres greenlight_production=# SELECT * FROM rooms; . . . greenlight_production=# UPDATE rooms SET access_code = 'passwort' WHERE id = 23; greenlight_production=# UPDATE rooms SET access_code = NULL WHERE id = 23;
2.6 BBB/Greenlight, Meeting ID bestimmen
Jedes Meeting besitzt eine BigBlueButton-Meeting ID, welche u.a. für API-Calls benötigt wird. Dass diese ID natürlich eine andere als die Greenlight UID ist, ist ja offensichtlich…
Eine Möglichkeit ist die Abfrage via API direkt.
Der checksum
-Parameter lässt sich aus Python folgendermaßen berechnen:
>>> import hashlib >>> hashlib.sha1(b'getMeetingsSUPERSICHER!!11').hexdigest()
Da dies maximal nervig ist, aber wieder SQL. Mittels Greenlights Datenbank lässt sich die Greenlight UID (hinterer Teil der URL) auf die BBB-Meeting ID abbilden.
alvar@bbb:/opt/greenlight$ sudo docker exec -it greenlight_db_1 bash bash-5.1# psql greenlight_production postgres greenlight_production=# SELECT bbb_id FROM rooms WHERE uid = 'general'; bbb_id ------------------------------------------ trololololololololololololololololololol (1 row)
2.7 BBB, Meeting streamen
Ein BBB-Meeting lässt sich via BigBlueButton Broadcaster ad hoc streamen.
Aktuell gibt es dafür die Domain stream.bbb.hsmr.cc
, welche ein CNAME auf stream.bbb.lurk.space
ist.
Zum Livestreamen eines Meetings bzw. eines Vortrags muss dann nur noch über den DevOps-Hai gesprungen werden.
- Bei Hetzner Cloud eine ordentliche VM mit eigenen CPU-Kernen klicken.
- DNS von
stream.bbb.lurk.space
auf die Kiste lenken. - Auf der Maschine den BBB Broadcaster und dessen Abhängigkeiten (Docker, Docker Compose) installieren, siehe README.
- Die
.env
-Datei erstellen, für die Meeting ID siehe Abschnitt oben. docker-compose up --build
, vielleicht in einemtmux
oder alternativ daemonized.- Wenn vorbei, dann Docker Compose beenden und die Aufzeichnung wegsichern.
- Die VM jetzt wieder löschen, sodass wir nur die paar Stunden Laufzeit bezahlen müssen.
- DNS wieder anpassen, z.B. auf den localhost zeigen lassen.
Das weggesicherte Video lässt sich mit folgendem ffmpeg-Befehl - bzw. einer Variante davon - zu einem handlichen Video kodieren.
ffmpeg \ -ss 00:11:00 -i meeting-20210703174740.mkv -ss 00:00:27 \ -c:v libx264 -preset faster -crf 23 -pix_fmt yuv420p -movflags +faststart \ -c:a aac -b:a 128k \ -metadata title="Zivilgesellschaft vs. Geheimdienste" \ -metadata author="Constanze Kurz" \ -metadata album="[hsmr] Hackspace Marburg, Sofaecke 01" \ -metadata year="2021" \ sofaecke01.mp4
- Das doppelte
-ss
liegt darin, dass das Seeken vor dem Input schneller, aber ungenauer ist. Somit wird also grob zu Minute elf gesprungen und danach passend zu 00:11:27. - Zur H.264-Zeile sind alle Flags bei ffmpeg dokumentiert.
- Audio ist AAC ohne Anpassungen.
- Metadaten basierend auf dieser Tabelle.