Ich war auf der Suche nach einer Text- und Videochat-Plattform, die - wenn möglich - ohne eigenen Client auskommt und im Webbrowser genutzt werden kann.
Die bekanntesten Lösungen dürften wohl Slack und Discord sein. Letzteres zielt eher auf die Gamer-Community während die Zielgruppe des ersteren Unternehmen sind. Außerdem sind beide 1.) Closed-Source Software und 2.) nicht dezentral aufgestellt.
Mit Jitsi Meet habe ich eine Lösung gefunden, bei der ich 1.) mich weder registrieren muss, 2.) einfach loslegen kann, 3.) meinen eigenen Server betreiben kann und 4.) auf Open-Source Software setzen kann.
Jitsi Meet setzt seinen Schwerpunkt auf Videochat. Für Textchat setze ich mich in einem anderen Artikel mit anderen Projekten auseinander.
Ich versuche hier, die Installation möglichst generisch zu halten. Daher ist für das Nachmachen schon einiges an Linux-Knowhow notwendig. Ich werde keine Copy-Paste Passagen bereitstellen, da diese oft Distributionsabhängig sind. Daher muss bei den Abschnitten mit Quellcode das Augenmerk auf die eigene Umgebung gelegt werden. Zur Erinnerung: Ich setze Gentoo-Linux auf meinem Server ein. Die meisten Anleitungen im Internet beziehen sich aber auf Debian-/Ubuntu-Linux.
Da ich auf meinem Server keine Kreuzabhängigkeiten oder auch Unvertraglichkeiten mit anderen Paketen haben möchte, habe ich entschieden, Jitsi Meet in einem Docker-Container zu installieren. Zum Nachmachen muss daher auf Deinem Server ebenfalls Docker installiert sein.
Um das Docker-Deployment zu vereinfachen, nutze ich Docker-Compose. Dafür wird von Jitsi Meet glücklicherweise eine docker-compose.yml zur Verfügung gestellt. Zum Nachmachen muss daher auf Deinem Server ebenfalls Docker-Compose installiert sein.
Zu allererst werden wir das Git-Repository in ein entsprechendes Verzeichnis klonen, z.B. /opt/docker-compose/.
cd /opt/docker-compose
git clone https://github.com/jitsi/docker-jitsi-meet.git
Dann müssen wir eine .env Datei erzeugen und an unsere Bedürfnisse anpassen. Glücklicherweise bringt das Repository gleich ein Beispiel mit.
cp env.example .env
vim .env
Die meisten Variablen sind schon mit sinnvollen Variablen vorbelegt:
#
# Basic configuration options
#
# Directory where all configuration will be stored.
CONFIG=~/.jitsi-meet-cfg
# Exposed HTTP port.
HTTP_PORT=8000
# Exposed HTTPS port.
HTTPS_PORT=8443
# System time zone.
TZ=Europe/Amsterdam
# IP address of the Docker host. See the "Running on a LAN environment" section
# in the README.
#DOCKER_HOST_ADDRESS=192.168.1.1
#
# Let's Encrypt configuration
#
# Enable Let's Encrypt certificate generation.
#ENABLE_LETSENCRYPT=1
# Domain for which to generate the certificate.
#LETSENCRYPT_DOMAIN=meet.example.com
# E-Mail for receiving important account notifications (mandatory).
#LETSENCRYPT_EMAIL=alice@atlanta.net
#
# Basic Jigasi configuration options (needed for SIP gateway support)
#
# SIP URI for incoming / outgoing calls.
#JIGASI_SIP_URI=test@sip2sip.info
# Password for the specified SIP account as a clear text
#JIGASI_SIP_PASSWORD=passw0rd
# SIP server (use the SIP account domain if in doubt).
#JIGASI_SIP_SERVER=sip2sip.info
# SIP server port
#JIGASI_SIP_PORT=5060
# SIP server transport
#JIGASI_SIP_TRANSPORT=UDP
#
# Authentication configuration (see README for details)
#
# Enable authentication.
#ENABLE_AUTH=1
# Enable guest access.
#ENABLE_GUESTS=1
#
# Advanced configuration options (you generally don't need to change these)
#
# Internal XMPP domain.
XMPP_DOMAIN=meet.jitsi
# Internal XMPP domain for authenticated services.
XMPP_AUTH_DOMAIN=auth.meet.jitsi
# XMPP domain for the MUC.
XMPP_MUC_DOMAIN=muc.meet.jitsi
# XMPP domain for the internal MUC used for jibri, jigasi and jvb pools.
XMPP_INTERNAL_MUC_DOMAIN=internal-muc.meet.jitsi
# XMPP domain for unauthenticated users.
XMPP_GUEST_DOMAIN=guest.meet.jitsi
# MUC for the JVB pool.
JVB_BREWERY_MUC=jvbbrewery
# XMPP user for JVB client connections.
JVB_AUTH_USER=jvb
# XMPP password for JVB client connections.
JVB_AUTH_PASSWORD=passw0rd
# STUN servers used to discover the server's public IP.
JVB_STUN_SERVERS=stun.l.google.com:19302,stun1.l.google.com:19302,stun2.l.google.com:19302
# Media port for the Jitsi Videobridge
JVB_PORT=10000
# TCP Fallback for Jitsi Videobridge for when UDP isn't available
JVB_TCP_HARVESTER_DISABLED=true
JVB_TCP_PORT=4443
# A comma separated list of APIs to enable when the JVB is started. The default is none.
# See https://github.com/jitsi/jitsi-videobridge/blob/master/doc/rest.md for more information
#JVB_ENABLE_APIS=rest,colibri
# XMPP component password for Jicofo.
JICOFO_COMPONENT_SECRET=s3cr37
# XMPP user for Jicofo client connections. NOTE: this option doesn't currently work due to a bug.
JICOFO_AUTH_USER=focus
# XMPP password for Jicofo client connections.
JICOFO_AUTH_PASSWORD=passw0rd
# XMPP user for Jigasi MUC client connections.
JIGASI_XMPP_USER=jigasi
# XMPP password for Jigasi MUC client connections.
JIGASI_XMPP_PASSWORD=passw0rd
# MUC name for the Jigasi pool.
JIGASI_BREWERY_MUC=jigasibrewery
# Minimum port for media used by Jigasi.
JIGASI_PORT_MIN=20000
# Maximum port for media used by Jigasi.
JIGASI_PORT_MAX=20050
# Disable HTTPS. This can be useful if TLS connections are going to be handled outside of this setup.
DISABLE_HTTPS=1
# Redirects HTTP traffic to HTTPS. Only works with the standard HTTPS port (443).
#ENABLE_HTTP_REDIRECT=1
Man muss die meisten Variablen nicht anpassen, da sie nur innerhalb der Docker-Umgebung zum Tragen kommen.
Die Variablen HTTP_PORT und HTTPS_PORT sollten mit Werten befüllt sein, die in die eigene Docker-Umgebung passen.
Man sollte aber die verschiedenen _PASSWORD und _SECRET Variablen mit besseren Werten füllen.
Wichtig ist allerdings die Variable DOCKER_HOST_ADDRESS. Hier setzt man die IP des Docker-Hosts, damit die Informationen sauber ins Internet propagiert werden können. Ansonsten würde die interne Docker-Adresse bekannt gemacht. Keine Angst, wenn es sich - wie hier bei mir - um eine private RFC1918-Adresse hinter einem NAT-Router handelt. Die offizielle NIC-Adresse wird per STUN ermittelt.
LETSENCRYPT benötige ich nicht, da ich HTTPS über meinen Reverse-Proxy mache.
Ein docker-compose up -d holt sich zunächst die benötigten Docker-Images und startet dann die Container im Hintergrund.
Damit ist Jitsi Meet schon vom Server per http://localhost:8000 erreichbar.
Um Jitsi Meet auch über das Internet erreichbar zu machen, setze ich einen Reverse-Proxy mit Apache ein. Im Internet gibt es auch Beispiel mit Nginx, aber ich nutze Apache.
Zunächst wollte ich Jitsi Meet über ein Unterverzeichnis eines schon bestehenden Virtualhost anbieten. Aber da hier Websockets benutzt werden, gab es beim Rewriting Probleme, so dass ich mich schließlich entschied, für Jitsi Meet einen eigenen Virtualhost anzulegen.
Wie man einen eigenen Virtualhost auf Eurem System anlegt, müsst Ihr leider selber herausfinden. Bei Ubuntu/Debian gibt es die Verzeichnisse /etc/apache2/sites-available und /etc/apache2/sites-enabled und das Tool a2enmod.
Zunächst konfiguriere ich den Virtualhost für HTTP. Darin konfiguriere ich die Umleitung zu HTTPS und setze die Ausnahmen für den Zugriff der Let's Encrypt Tools.
Define jitsi-sn jitsi.example.com
<VirtualHost *:80>
#ServerAdmin contact@example.com
ServerName ${jitsi-sn}
CustomLog /var/log/apache2/jitsi_access_log vhost
ErrorLog /var/log/apache2/jitsi_error_log
<IfDefine SSL>
<ifmodule mod_rewrite.c>
RewriteEngine On
RewriteCond "%{REQUEST_URI}" "!^/\.well-known/acme-challenge(/[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-]*)?$"
RewriteRule "^/(.*)" "https://%{HTTP_HOST}/$1" [last,redirect=301]
Alias /.well-known/acme-challenge "/var/www/letsencrypt/.well-known/acme-challenge"
<Directory "/var/www/letsencrypt/.well-known/acme-challenge">
Require all granted
AllowOverride All
AddDefaultCharset Off
Header set Content-Type "text/plain"
</Directory>
</ifmodule>
</IfDefine>
<IfDefine !SSL>
ProxyPreserveHost On
ProxyRequests Off
RequestHeader set X-Forwarded-Proto "https"
<Location />
ProxyPass http://localhost:8000/
ProxyPassReverse http://localhost:8000/
</Location>
</IfDefine>
</VirtualHost>
Mit /etc/init.d/apache2 restart starte ich den Webserver neu und mache die Konfigurationsänderungen bekannt.
Da ich die Verbindung natürlich mit SSL absichern möchte, brauche ich auch entsprechende Zertifikate. Das geht zügig mit Let's Encrypt.
~/letsencrypt/letsencrypt-auto certonly -d jitsi.example.com --webroot
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for jitsi.example.com
Input the webroot for jitsi.example.com: (Enter 'c' to cancel): /var/www/letsencrypt
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/jitsi.example.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/jitsi.example.com/privkey.pem
Your cert will expire on 2019-03-12. To obtain a new or tweaked
version of this certificate in the future, simply run
letsencrypt-auto again. To non-interactively renew *all* of your
certificates, run "letsencrypt-auto renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF:https://eff.org/donate-le
Jetzt muss ich nur noch die Konfiguration für HTTPS vornehmen:
<IfDefine SSL>
<VirtualHost *:443>
ServerAdmin contact@${jitsi-sn}
ServerName ${jitsi-sn}
CustomLog /var/log/apache2/jitsi_access_log vhost
ErrorLog /var/log/apache2/jitsi_error_log
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Strict-Transport-Security "max-age=31536000"
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCompression off
SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerCN Off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
SSLOptions +StdEnvVars
SSLSessionTickets Off
SSLCipherSuite EECDH+AESGCM:AES256+EECDH:AES128+EECDH
SSLHonorCipherOrder on
SSLCertificateFile /etc/letsencrypt/live/${jitsi-sn}/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/${jitsi-sn}/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/${jitsi-sn}/fullchain.pem
SSLCACertificateFile /etc/ssl/ca-certs.pem
ProxyPreserveHost On
ProxyRequests Off
RequestHeader set X-Forwarded-Proto "https"
<Location />
ProxyPass http://localhost:8000/
ProxyPassReverse http://localhost:8000/
</Location>
</VirtualHost>
</IfDefine>
Damit ist Jitsi Meet über die URL https://jitsi.example.com erreichbar.
Mit Jitsi Meet gibt es eine Videochat-Lösung, die sich mit Docker und Apache als Reverse-Proxy relativ einfach auf einem eigenen Server installieren lässt und keine Registrierung bei einem zentralen Dienstbetreiber erfordert.