Nextcloud Talk mit coturn und eigenem Signaling-Server (High Performance Backend)

Mit der „Talk“-App unterstützt Nextcloud auch Videokonferenzen. Dafür wird mindestens STUN (Session Traversal Utilities for NAT) und TURN (Traversal Using Relay NAT) benötigt, um die Kommunikation zwischen den Teilnehmern hinter NAT-Routern zu ermöglichen. Die übliche Lösung unter Linux ist dafür coturn.

Mit coturn funktioniert Talk in der Regel schon ganz gut, wenn sich nicht mehr als 4-5 Teilnehmer in einer Sitzung befinden. Allerdings erfolgt die Verbindung der Clients dann direkt untereinander ohne einen zentralen Server für den Austausch von Audio- und Video. Bei mehr als 5 Clients steigt Aufwand für die Kommunikation überproportional und ist irgendwann gar nicht mehr möglich, weshalb Nextcloud Talk auch warnt, wenn mehr als 5 Clients verbunden sind.

Die Lösung für Videokonferenzen mit vielen Clients ist ein separater Signaling-Server, das „High Performance Backend“. Damit werden die Video- und Audio-Daten der Clients über einen zentralen Server verteilt, so dass jeder einzelne Client nur noch die Verbindung zum Server benötigt. Die Zahl der möglichen Clients ist dann nur noch durch die Leistung und Netzanbindung des Servers begrenzt. In der Vergangenheit konnte man diesen Server nur kostenpflichtig als Dienst mieten, wobei die Preisgestaltung sich ganz klar an Firmennutzern orientiert. Im Mai 2020 wurde dann aber erfreulicherweise die Freigabe des Servers als Open Source bekannt gegeben, womit das auch für private Nutzer und Institutionen mit wenig Budget interessant ist.

Bei der nachfolgende Beschreibung der Installation gehe ich davon aus, dass bereits eine Nextcloud-Installation mit Apache als Webserver vorhanden ist und Linux auf Basis von Ubuntu verwendet wird. Außerdem nutze ich Docker für NATS, was man ebenfalls vorher einrichten muss. Siehe dazu auch die Anleitung bei Docker selbst.

Systemvoraussetzungen

Für den Betrieb von Nextcloud mit eigenem Signaling-Server sollte eine Umgebung mit mindestens 4 CPU-Kernen, 16 GB RAM und einer Anbindung mit 1 GBit/s (in beide Richtungen) verwendet werden. Virtuelle Server sollten kein grundsätzliches Problem sein, allerdings ist die Netzwerkanbindung hier mitunter problematisch.

Einrichten von coturn und erste Tests

Siehe dazu auch https://nextcloud-talk.readthedocs.io/en/latest/TURN/.

coturn kann als Paket installiert werden:

apt install coturn

Danach muss der Server mit folgendem Eintrag in /etc/default/coturn aktiviert werden:

TURNSERVER_ENABLED=1

Damit coturn später mit einem eigenen User läuft und nicht als root, legt man bei Bedarf einen System-User dafür wie folgt an, falls dieser nicht schon existiert:

groupadd turnserver
useradd --system --gid turnserver --shell /bin/false -comment "Coturn" turnserver

Für die Nutzung mit Nextcloud Talk sind schließlich noch folgende Einträge in der Konfigurationsdatei /etc/turnserver.conf erforderlich. Die Datei enthält viele Einträge bereits als auskommentierte Zeilen, erkennbar am „#“-Zeichen am Zeilenanfang. Hier genügt es, dieses Zeichen zu entfernen und den Rest nach Bedarf anzupassen:

listening-port=3478
listening-ip=<IPv4-Adresse des Servers>
listening-ip=<IPv6-Adresse des Servers>
fingerprint
lt-cred-mech
use-auth-secret
static-auth-secret=<Secret>
realm=<FQDN des Servers>
total-quota=0
bps-capacity=0
no-tls
no-dtls
stale-nonce
no-stdout-log
log-file=/var/log/coturn.log
no-loopback-peers
no-multicast-peers
proc-user=turnserver
proc-group=turnserver

lt-cred-mech wird nur für Versionen unter 4.5.0.8 benötigt.

no-loopback-peers wird nur für Versionen unter 4.5.1.0 benötigt.

Bei realm= gibt man den Namen des Servers an. Man benötigt nicht zwingend eine eigene Subdomain dafür, aber ich habe mir angewöhnt, für solche Dienste eigene Namen zu reservieren, wie z.B. turnserver.example.com (statt example.com die eigene Domain), dann ist klar, wofür dieser Server verwendet wird.

Als <Secret> muss eine zufällig Zeichenfolge angegeben werden, die dann später auch in Nextcloud und im Signaling-Server eingetragen wird. Zur Erzeugung kann man ein Kommando wie openssl rand -hex 32 verwenden, mit dem ein 32 Zeichen langer Text erzeugt wird.

Ein Hinweis zu den Optionen no-tls und no-dtls, mit denen die Nutzug von TLS und DTLS deaktiviert wird: Nextcloud unterstützt die Verwendung von (D)TLS nicht, weil es keinen echten Sicherheitsgewinn bringt. Näheres dazu siehe auch hier:

https://github.com/nextcloud/spreed/issues/257

Schließlich startet man coturn:

service coturn start

Zur Angabe der IP-Adressen

Der Eintrag listening-ip kann mehrfach vorhanden sein. Jede IP-Adresse, unter der der Server erreichbar sein soll, muss hier genannt werden. Überweise ist das eine IPv4-Adresse und eine IPv6-Adresse. Hat der Server nur eine IPv4-Adresse, genügt diese natürlich auch als einziger Eintrag.

Port 80 statt 3478?

Restriktivere Firewalls in Firmennetzwerken erlauben mitunter keine Verbindungen auf Port 3478. Als Workaround wird mitunter empfohlen, auf Port 80 (und ggf. eine andere IP-Adresse als der Webserver für Nextcloud) auszuweichen. Das Problem dabei ist aber, dass häufig auch ein Proxy verwendet wird, über den nur HTTP auf Port 80 möglich ist. TURN würde in diesem Fall auch dann nicht funktionieren, wenn man es auf Port 80 konfiguriert. Hinzu kommt, dass neben diesem Port für die weitere Kommunikation über WebRTC zusätzliche Ports verwendet werden, die ebenfalls durch die Firewall gesperrt sein könnten. Eine sinnvollere Lösung ist es daher, bei Problemen mit der zuständigen Administration zu sprechen, damit die Firewall-Konfiguration angepasst wird.

Test und Konfiguration in Nextcloud

Für den Test von Coturn kann man Trickle ICE verwenden.

Dort löscht man zunächst den Eintrag für den Server bei Google und gibt dann die Adresse des eigenen Servers im Format stun:<Servername>:3478 ein. Mit „Gather candidates“ kann man dann prüfen, ob der STUN-Server eine Antwort zurückliefert. Die Antwort sollte ohne große Verzögerung erfolgen und mit „Done“ am Ende der Liste abgeschlossen sein.

In Nextcloud wird Coturn in den Einstellungen zu Talk wie folgt eingetragen:

Beim STUN-Server gibt man die Adresse im Format <Servername>:3478 ein. Beim TURN-Server fügt man zunächst mit „+“ einen neuen Eintrag hinzu und gibt dann als Server-Adresse ebenfalls <Servername>:3478 an und als Secret die Angabe für static-auth-secret aus /etc/turnserver.conf. Als Protokoll kann man die Voreinstellung für UDP and TCP belassen, da Coturn beide Protokolle unterstützt.  Nach der Eingabe wird die Verbindung jeweils geprüft und mit einem kleinen Haken bestätigt, wenn sie erfolgreich war.

Ab diesem Zeitpunkt sollte Nextcloud Talk bereits grundsätzlich nutzbar sein. Wer nur Sitzungen mit maximal 4-5 Personen braucht, sollte damit prinzipiell arbeiten können.

Erweiterung mit Signaling-Server

Für den Betrieb des Signaling-Server sind mehrere Komponenten erforderlich:

  • Janus für die Verteilung der Audio- und Video-Streams zwischen den Clients über WebRTC
  • NATS as Messaging-Server
  • Spreed Signaling-Server

Einrichten von Janus

PPA für Ubuntu

Für Janus habe ich das PPA von https://launchpad.net/~fancycode/+archive/ubuntu/janus verwendet. Dieses PPA bringt alle erforderlichen Komponenten mit. Für die Installation sind folgende Schritte nötig:

add-apt-repository ppa:fancycode/janus
apt update
apt install janus

Konfiguration

Nun trägt man in /etc/janus/janus.jcfg folgende Optionen im Abschnitt nat: { ein:

nat: {
        stun_server = "<server>"
        stun_port = 3478
        nice_debug = false
        full_trickle = true
# ...
        turn_rest_api_key = "<key>"
# ...
}

Für <server> ist der Name des Servers anzugeben, über den Coturn erreichbar ist.

Für <key> gibt man eine zufällige Zeichenfolge ein, die man sich wie bei Coturn auch mit openssl rand -hex 16 erzeugen kann, hier aber mit 16 statt 32 Zeichen.

Desweiteren in /etc/janus/janus.transport.http.jcfg folgendes:

general: {
# ...
        json = "idented"
        base_path = "/janus"
        http = true
        port = 8088
        ip = 127.0.0.1
        https = false
# ...
}

Falls Port 8088 auf dem eigenen Server bereits für andere Dienste belegt ist, muss dieser entsprechend angepasst werden. Der Port wird später auch im Signaling-Server angegeben.

In /etc/janus/janus.transport.websockets.jcfg ist auch noch die IP-Adresse anzupassen, damit nur lokale Verbindungen möglich sind:

general: {
# ...
        ws = true
        ws_port = 8188
        ws_ip = 127.0.0.1
        wss = false
# ...
}

Auch hier gilt, dass man statt Port 8188 bei Bedarf auch einen anderen Port verwenden kann. Der Port muss später nur korrekt im Signaling-Server angegeben werden.

Am Ende startet man Janus wie folgt:

systemctl start janus

Einrichten von NATS

Die einfachste Variante, NATS einzurichten, ist die Verwendung von Docker:

docker pull nats:latest
docker run --name=natsserver -d -p 127.0.0.1:4222:4222 -ti --restart=always nats:latest

NATS ist dann lokal auf Port 4222 ansprechbar und wird beim Systemstart automatisch gestartet. Weiter ist nichts erforderlich.

Einrichten des Signaling-Servers

Herunterladen der Quellen und erzeugen der Server-Binaries

Für den Signaling-Server muss man sich die Quellen von Github herunterladen und den Server daraus selbst erstellen:

apt install golang-go
cd /etc/
git clone https://github.com/strukturag/nextcloud-spreed-signaling.git
cd /etc/nextcloud-spreed-signaling
make build

Erzeugen der lokalen Konfiguration

Nach dem erfolgreichen Durchlauf erstellt man sich eine lokale Konfiguration in /etc/nextcloud-spreed-signaling/server.conf:

cd /etc/nextcloud-spreed-signaling
cp server.conf.in server.conf

Diese wird dann noch wie folgt angepasst:

[http]
listen = 127.0.0.1:8086

[sessions]
hashkey = <session-hashkey>
blockkey = <session-blockkey>

[backend]
backends = backend1

[backend1]
url = <URL des Nextcloud-Servers>
secret = <Nextcloud-Secret>

[nats]
url = nats://localhost:4222

[mcu]
type = janus
url = ws://127.0.0.1:8188

[turn]
apikey = <API-Key von Janus (turn_rest_api_key)>
secret = <Secret von Coturn (static-auth-secret)>

Für <session-hashkey> und <session-blockkey> verwendet man jeweils die Ausgabe von openssl rand -hex 32.

<Nextcloud-Secret> ist das Secret, das man auch in Nextcloud angeben muss. Auch hier kann man openssl rand -hex 32 zur Erzeugung verwenden.

Erstellen der Systemd-Unit

Damit der Signaling-Server als Dienst nutzbar ist, ist wie bei Coturn ein eigener System-User erforderlich:

groupadd signaling
useradd --system --gid signaling --shell /bin/false -comment "Nextcloud Signaling" signaling

Danach erstellt man die Datei /etc/systemd/system/nextcloud-signaling.service mit folgendem Inhalt:

[Unit]
Description=Nextcloud Talk signaling server

[Service]
ExecStart=/etc/nextcloud-spreed-signaling/bin/signaling --config /etc/nextcloud-spreed-signaling/server.conf
User=signaling
Group=signaling
Restart=on-failure

[Install]
WantedBy=multi-user.target

Die Unit wird dann wie folgt aktiviert und gestartet:

systemctl daemon-reload
systemctl enable nextcloud-signaling
systemctl start nextcloud-signaling

Kontrolle der Dienste

Mit folgenden Kommandos kann man prüfen, ob die Dienste korrekt laufen:

Janus

journalctl -u janus

Warnungen wie [WARN] HTTPS webserver disabled kann man ignorieren. Es sollten aber keine Fehlermeldungen vorliegen.

Signaling-Server

journalctl -u nextcloud-signaling

Hier sollte man darauf den Eintrag Listening on 127.0.0.1:8086 achten und prüfen, ob der TURN-Server korrekt verwendet wird (Adding "turn:turn.0x0c.de:3478?transport=udp" as TURN server und Adding "turn:turn.0x0c.de:3478?transport=tcp" as TURN server). Falls später der Verbindunsaufbau dennoch nicht klappt, hat man eventuell das Secret von Coturn nicht korrekt eingetragen.

Coturn als Systemd-Unit

Coturn wird nur mit einem init-Script installiert. Wer statt dessen eine Systemd-Unit bevorzugt, kann dazu die Datei /etc/systemd/system/turnserver.service mit folgendem Inhalt erstellen:

[Unit]
Description=coturn
Documentation=man:coturn(1) man:turnadmin(1) man:turnserver(1)
After=syslog.target network.target

[Service]
Type=forking
User=turnserver
Group=turnserver
RuntimeDirectory=turnserver
RuntimeDirectoryMode=0750
EnvironmentFile=/etc/default/coturn
PIDFile=/run/turnserver/turnserver.pid
ExecStart=/usr/bin/turnserver --daemon --pidfile /run/turnserver/turnserver.pid --syslog -c /etc/turnserver.conf $EXTRA_OPTIONS
Restart=on-abort
LimitCORE=infinity
LimitNOFILE=1000000
LimitNPROC=60000
LimitRTPRIO=infinity
LimitRTTIME=7000000
CPUSchedulingPolicy=other
UMask=0007

[Install]
WantedBy=multi-user.target

Danach deaktiviert man das init-Script und stellt auf die Nutzung der Systemd-Unit um:

update-rc.d coturn disable
systemctl daemon-reload
systemctl disable coturn
systemctl enable turnserver
systemctl start turnserver

Zur Sicherheit sollte man prüfen, dass die Unit korrekt gestartet wurde:

systemctl status turnserver

Apache-Proxy konfigurieren

Für den Signaling-Server habe ich eine eigene Subdomain in Apache mit HTTPS auf Basis von Let’s Encrypt angelegt. Darin wurde ein Reverse-Proxy konfiguriert, der den Zugang zum Signaling-Server über HTTPS ermöglicht. Dazu sind auch folgende Module erforderlich:

  • proxy
  • proxy_http
  • proxy_wstunnel
RewriteEngine On
RewriteRule ^/standalone-signaling/spreed$ - [L]
RewriteRule ^/standalone-signaling/api/(.*) http://127.0.0.1:8086/api/$1 [L,P]
ProxyPass "/standalone-signaling/" "ws://127.0.0.1:8086/"

Falls man statt 8086 in der Konfiguration des Signaling-Servers einen anderen Port verwendet, muss dieser natürlich hier entsprechend angegeben werden.

Konfiguration des Signaling-Servers in Nextcloud

In Nextcloud fügt man den Signaling-Server ähnlich wie STUN/TURN in der Konfiguration von Talk hinzu.

Dabei gibt man die URL im Format https://<servername>/standalone-signaling an. Das Secret ist die Angabe aus der Backend-Konfiguration des Signaling-Servers.

Nachdem man Server-Adresse und Secret angegeben hat, sollte zur Bestätigung auch „OK: Running version:“ gefolgt von einer längeren Zeichenfolge erscheinen.

Öffentlichen Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Dies ist kein Kontaktformular! Wenn Du mir eine persönliche Nachricht schreiben möchtest, benutze die E-Mail-Adresse in meinem Impressum.

Du kannst die folgenden HTML-Tags im Kommentar verwenden:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>