3.2. Umsetzung

3.2.1. Matrix Server

Der Matrix-Server wurde mithilfe einer Docker Compose definition aufgesetzt, um die Installation und Konfiguration zu vereinfachen.

Die folgende YAML zeigt die Definition von Matrix über Docker Compose:

networks:
matrix:
    external: true

services:
synapse:
    image: ghcr.io/element-hq/synapse:latest
    restart: unless-stopped
    environment:
    - SYNAPSE_SERVER_NAME=${SYNAPSE_SERVER_NAME}
    - SYNAPSE_CONFIG_PATH=${SYNAPSE_CONFIG_PATH}
    - SYNAPSE_REPORT_STATS=${SYNAPSE_REPORT_STATS}
    - POSTGRES_DB=${POSTGRES_DB}
    - POSTGRES_HOST=${POSTGRES_HOST}
    - POSTGRES_USER=${POSTGRES_USER}
    - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    volumes:
    - ./data:/data
    depends_on:
    - db
    ports:
    - "127.0.0.1:8008:8008/tcp"
    networks:
    - matrix

db:
    image: docker.io/postgres:latest
    environment:
    - POSTGRES_DB=${POSTGRES_DB}
    - POSTGRES_USER=${POSTGRES_USER}
    - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    - POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C
    volumes:
    - ./schemas:/var/lib/postgresql/data
    networks:
    - matrix
    labels:
    - "com.centurylinklabs.watchtower.enable=true"

Config-File generieren

Zuerst generieren wir ein Config-File für unseren Matrix Server, welches wir später nutzen um den Server zu starten.

docker run -it --rm \
--mount type=volume,src=synapse-data,dst=/data \
-e SYNAPSE_SERVER_NAME=dva.mahart.ma \
-e SYNAPSE_REPORT_STATS=yes \
matrixdotorg/synapse:latest generate

Matrix server Konfiguration

Nun müssen wir die generierte Konfigurationsdatei anpassen, um unseren Server zu konfigurieren. .. code-block:

server_name: "dva.mahart.ma"
pid_file: /data/homeserver.pid
listeners:
  - port: 8008
    tls: false
    type: http
    x_forwarded: true
    resources:
      - names: [client, federation]
        compress: false
database:
  name: psycopg2
  args:
    user: "synapse"
    password: "CxbBgJcd>E=nBBD%tXsZ8n#k))TJ&P@="
    dbname: "synapse"
    host: db
    cp_min: 5
    cp_max: 10
log_config: "/data/dva.mahart.ma.log.config"
media_store_path: /data/media_store
enable_registration: true
enable_registration_without_verification: true
registration_shared_secret: "i5Mnvhgi28N;3Y5JA@ILi=0XcoMLt0Wx0uGs74_.JJ0H5EO0yy"
report_stats: false
macaroon_secret_key: "0Hd=1:G^jZULDT5wX90zlVIoQ;0~ERqQWH7P7h9K#7u.Ay0w5W"
form_secret: "Og=VEE5g55AqoVz;CIpCqt2Y@ocl02Ll6;C+S@kbtKLPew#@Cx"
signing_key_path: "/data/dva.mahart.ma.signing.key"
trusted_key_servers:
  - server_name: "matrix.org"
turn_uris: [ "turn:turn.dva.mahart.ma?transport=udp", "turn:turn.dva.mahart.ma?transport=tcp" ]
turn_shared_secret: "Y38BDIk8vDv5dLVQwUod3cPXMfZqUSAni2skYA7ZP5P73UefeKq8AVvJ2ajWMyoK"
turn_user_lifetime: 86400000
turn_allow_guests: true

Grundlegende Serverkonfiguration

Der server_name ist der eindeutige Name des Matrix-Servers im Netzwerk. In diesem Fall ist dies „dva.mahart.ma“. Die Einstellung pid_file gibt den Pfad zur Datei an, die die Prozess-ID (PID) des Servers speichert, was für das Management des laufenden Prozesses nützlich ist.

Listener-Konfiguration

Der Server hört auf Port 8008, wie durch die Einstellung port festgelegt. Da tls auf false gesetzt ist, wird TLS/SSL nicht direkt vom Server verwendet, sondern sollte durch einen vorgeschalteten Proxy gehandhabt werden. Der type des Listeners ist http, was den Hauptkommunikationsweg für Clients und andere Server darstellt. Die Einstellung x_forwarded ist auf true gesetzt, was darauf hindeutet, dass der Server hinter einem Proxy läuft, der die X-Forwarded-For-Header setzt.

Datenbankkonfiguration

Es wird PostgreSQL verwendet, wie durch die Angabe name: psycopg2 dargestellt. Die Argumente unter args enthalten wichtige Verbindungsinformationen wie Benutzername, Passwort, Datenbankname, Host sowie die minimale und maximale Anzahl von Verbindungen im Pool (cp_min und cp_max).

Registrierungs- und Sicherheitseinstellungen

Die Möglichkeit für Nutzer, sich zu registrieren, ist durch enable_registration: true aktiviert, und eine Verifizierung bei der Registrierung ist nicht notwendig, da enable_registration_without_verification: true gesetzt ist. Die registration_shared_secret ist ein sicherer Schlüssel, der zur Authentifizierung bei der Registrierung dient und sicher aufbewahrt werden sollte.

TURN-Server

Die turn_uris bieten Konfigurationen für den TURN-Server, der zur Überwindung von NAT für VoIP und Videoanrufe wichtig ist. Es sind URIs sowohl für UDP als auch für TCP konfiguriert, was eine breite Kompatibilität sicherstellt. Der turn_shared_secret dient zur Authentifizierung bei der Nutzung des TURN-Servers und sollte geheim und sicher aufbewahrt werden.

Dieser Text bietet eine umfassende Beschreibung der wichtigsten Konfigurationsaspekte des Matrix-Servers und kann als Basis für eine detailliertere Dokumentation oder als Überprüfungsleitfaden für die Konfigurationseinstellungen dienen.

Weitere Konfigurationen

hier sind einige weitere Konfigurationen, die man noch in der Datei hinfügen könnte:

# Additional security settings
enable_metrics: false
min_user_id_length: 5
password_policy:
  enabled: true
  minimum_length: 8
  require_digit: true
  require_symbol: true
  require_lowercase: true
  require_uppercase: true

# Module configuration
modules:
  - module: "synapse.module.ExampleModule"
    config:
      example_option: "value"

Sicherheitseinstellungen:

enable_metrics: false deaktiviert das Sammeln von Metriken, was die Privatsphäre der Benutzer erhöht. min_user_id_length: 5 und die Passwortrichtlinie erhöhen die Sicherheit der Benutzerkonten.

Modulkonfiguration:

Hier können Sie zusätzliche Module konfigurieren, wie das ExampleModule, um die Funktionalität des Servers zu erweitern.

3.2.2. Reverse Proxy über Traefik

Traefik ist ein moderner Edge-Router, der speziell für Containerumgebungen entwickelt wurde. Traefik kann als Reverse-Proxy und Load-Balancer für Webanwendungen und Microservices eingesetzt werden. Der Edge-Router empfängt Daten über geöffnete Ports und leitet sie an die entsprechenden Dienste weiter. Besonders ist hierbei, dass Traefik automatisch neue Dienste erkennt und konfiguriert, sogar live während des Betriebs. Auch die Konfiguration findet vollständig über die Mittel des Container-Environments statt, beispielsweise über Labels.

Traefik funktioniert nicht nur in der Docker-Umgebung sondern auch in Kubernetes, OpenShift und den meisten anderen Container-Orchestrierungssystemen.

Traefik ist in Golang entwickelt und unter der MIT-Lizenz veröffentlicht.

Die Docker-Compose-Datei für Traefik inklusive Auto-Updates über Watchtower und Dashboard sieht wie folgt aus:

networks:
matrix:
    external: true

services:
watchtower:
    image: containrrr/watchtower
    container_name: watchtower
    restart: unless-stopped
    volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    command: --label-enable --interval=43200 --cleanup
    networks:
    - matrix

traefik:
    image: "traefik:v2.11"
    container_name: "traefik"
    command:
    #- "--log.level=DEBUG"
    #- "--api.insecure=true"
    - "--api.dashboard=true"
    - "--providers.docker=true"
    - "--providers.docker.exposedbydefault=false"
    - "--providers.docker.network=web"
    - "--entrypoints.web.address=:80"
    - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
    - "--entrypoints.websecure.address=:443"
    - "--entrypoints.webmatrix.address=:8448"
    - "--entrypoints.webmatrix.http.tls.options=default"
    - "--entrypoints.webmatrix.http.tls.certresolver=myresolver"
    - "--entrypoints.websecure.http.middlewares=https_config@docker,www-redirect@docker"
    - "--entrypoints.websecure.http.tls.options=default"
    - "--entrypoints.websecure.http.tls.certresolver=myresolver"
    - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
    #- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
    - "--certificatesresolvers.myresolver.acme.email=mahartma@mahartma.com"
    - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"

    labels:
    traefik.enable: true

    # https redirect
    traefik.http.middlewares.https_config.redirectscheme.scheme: "https"
    traefik.http.middlewares.https_config.redirectscheme.permanent: true

    # www -> non-www
    traefik.http.middlewares.www-redirect.redirectregex.regex: "^https://www.(.*)"
    traefik.http.middlewares.www-redirect.redirectregex.replacement: "https://$${1}"
    traefik.http.middlewares.www-redirect.redirectregex.permanent: true

    # basic-auth
    # Note: when used in docker-compose.yml all dollar signs in the hash need to be doubled for escaping.
    # echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g
    traefik.http.middlewares.dev-auth.basicauth.users: "dva:$$apr1$$gUBBy11O$$w.owgrn.62lbLkM2ON.1p0" # password: secure

    # dashboard
    traefik.http.routers.api.rule: Host(`traefik.dva.mahart.ma`)
    traefik.http.routers.api.service: api@internal
    traefik.http.routers.api.middlewares: dev-auth
    traefik.http.routers.api.entrypoints: websecure

    # auto updates via watchtower
    com.centurylinklabs.watchtower.enable: true

    ports:
    - "443:443"
    - "80:80"
    - "8448:8448"

    volumes:
    - "/var/lib/traefik/letsencrypt:/letsencrypt"
    - "/var/run/docker.sock:/var/run/docker.sock:ro"

    networks:
    - matrix
    - default

    restart: unless-stopped

Dass Traefik die Discovery innerhalb der Docker-Umgebung durchführen kann, wird der Docker Socket als Volume gemountet. Ein weiteres Verzeichnis wird für die Zertifikate von Let’s Encrypt gemountet, um die Private- und Public-Keys zu speichern. Traefik exposed außerdem die Ports 80 (http), 443 (https), um den Datenverkehr zu empfangen und an die entsprechenden Dienste weiterzuleiten.

Wir verwenden unterschiedliche Labels zur Konfiguration und dem Aktivieren von Middlewares, um die Sicherheit und Funktionalität des Traefik-Setups zu gewährleisten:

  • Die Entrypoints web und websecure sind für HTTP und HTTPS konfiguriert, während webmatrix für den Matrix-Server konfiguriert ist. Die Entrypoints sind für die Weiterleitung des Datenverkehrs an die entsprechenden Dienste verantwortlich und hören auf den entsprechenden Ports.

  • Der certresolver wird verwendet, um die TLS-Zertifikate für die Verschlüsselung des Datenverkehrs zu verwalten und zu aktualisieren. Hier wird die ACME Challenge für die automatische Zertifikatsverwaltung aktiviert und die E-Mail-Adresse für Benachrichtigungen konfiguriert. Wir verwenden die Let’s Encrypt ACME-Server für die Zertifikatsverwaltung.

  • Die Middleware basicauth ermöglicht die Authentifizierung von Benutzern über HTTP Basic Auth.

  • Die Middleware redirectscheme leitet den Datenverkehr von HTTP auf HTTPS um.

  • Die Middleware redirectregex ermöglicht die Umleitung von URLs basierend auf einem regulären Ausdruck, z.B. von www zu non-www.

Dashboard

Traefik bietet ein Dashboard an, das über den Hostnamen traefik.dva.mahart.ma erreichbar ist. Das Dashboard ist über HTTPS gesichert und erfordert eine Authentifizierung über HTTP Basic Auth. Das Dashboard ermöglicht die Überwachung von Traefik und den verwalteten Diensten.

Um Traefik mit dem Matrix-Server zu verwenden, müssen wir die entsprechenden Labels in der Docker-Compose-Datei des Matrix Setups hinzufügen:

labels:
  # Alternatively, for Traefik version 2.0:
  - traefik.enable=true
  - "traefik.http.routers.matrix.rule=Host(`dva.mahart.ma`)"
  - "traefik.http.routers.matrix.entrypoints=websecure"
  - "traefik.http.routers.matrix.tls.certresolver=myresolver"
  - "traefik.http.routers.matrix.service=matrix-matrix"
  - "traefik.http.services.matrix-matrix.loadbalancer.server.port=8008"
  - "traefik.http.routers.matrix1.rule=Host(`dva.mahart.ma`)"
  - "traefik.http.routers.matrix1.entrypoints=webmatrix"
  - "traefik.http.routers.matrix1.tls.certresolver=myresolver"
  - "traefik.http.routers.matrix1.service=matrix1-matrix1"
  - "traefik.http.services.matrix1-matrix1.loadbalancer.server.port=8008"
  #- "traefik.http.routers.matrix.middlewares=dev-auth" # enable basic auth
  - "com.centurylinklabs.watchtower.enable=true"

Die Labels konfigurieren, welche Dienste von Traefik verwaltet werden sollen, und wie der Datenverkehr an diese Dienste weitergeleitet werden soll. Hier wird konfiguriert, dass der Matrix-Server über die Host-Adresse „dva.mahart.ma“ erreichbar ist und dass der Datenverkehr über die Entry-Points „websecure“ und „webmatrix“ geleitet wird. Die Labels konfigurieren auch die TLS-Zertifikate für die Verschlüsselung des Datenverkehrs und die Portweiterleitung an den Matrix-Server.

Quellen:

3.2.3. TURN Server

Um unseren Matrix Server von einem Chat Server zu einem Sprachanruf Server zu erweitern, benötigen wir einen TURN Server. TURN Server ermöglichen VoIP Relaying, mit welchem Sprach-Audio auf unserem Matrix Server übertragen wird.

3.2.4. coturn

coturn ist eine Implementierung eines TURN Servers, welche wir in unserem Projekt nutzen werden.

Installation

Die Installation erfolgt bequem durch folgenden Befehl: sudo apt install coturn

Konfiguration

Nun muss der TURN Server richtig konfiguriert werden, um die Kopplung mit unserem Matrix Server zu ermöglichen sowie die Sicherheit zu stärken. In unserer Konfigurationsdatei (/etc/turnserver.conf) setzen wir daher folgende Werte:

use-auth-secret
static-auth-secret=[secret]
realm=turn.myserver.org

Wir legen fest dass unser TURN Server, den von uns generierten Schlüssel nutzen soll, dieser wird später genutzt zur sicheren Passwort Generierung. Um einen Schlüssel zu generieren können wir folgenden Befehl nutzen: pwgen -s 64 1

realm dient als Anzeigename in Authentifizierungsabläufen und häufig wird hier einfach der Server Name angegeben.

TURN ermöglicht es Nutzern ein Relay anzufordern, welches zu beliebigen IP Adressen und Ports ein Verbindung aufbauen kann, daher ist es sinnvoll bestimmte IP Adressen auszuschließen:

no-multicast-peers
denied-peer-ip=10.0.0.0-10.255.255.255
denied-peer-ip=192.168.0.0-192.168.255.255
denied-peer-ip=172.16.0.0-172.31.255.255
denied-peer-ip=0.0.0.0-0.255.255.255
denied-peer-ip=100.64.0.0-100.127.255.255
denied-peer-ip=127.0.0.0-127.255.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=192.88.99.0-192.88.99.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=240.0.0.0-255.255.255.255
allowed-peer-ip=10.0.0.1

VoIP erfolgt ausschließlich über UDP, daher blockieren wir TCP Verbindungen:

no-tcp-relay

Zudem ist es keine schlechte Idee die Anzahl der Streams pro Nutzer einzuschränken, um zu verhindern dass ein Nutzer unbegrenzt Ressource in Anspruch nimmt:

user-quota=12 # Video Anrufe nutzen 4 Streams, daher 12 Streams = 3 gleichzeitige relayed Anrufe pro Nutzer
total-quota=1200

Die letzte Einstellung aktiviert die TLS Verschlüsselung für unseren TURN Server:

# TLS Zertifikate Datei
cert=/pfad/zu/fullchain.pem

# TLS Private Key Datei
pkey=/pfad/zu/privkey.pem

# Die folgenden zwei Einstellungen müssen kommentiert werden mit #
# no-tls
# no-dtls

Nun ist unser TURN Server fertig konfiguriert, mit TLS Verschlüsselung und grundlegenden Sicherheitsvorkehrungen.

3.2.5. Authentifizierungsserver Sydent

Sydent ist ein zentraler Bestandteil des Matrix-Ökosystems und nimmt die Rolle eines Identitätsservers ein.

Allgemein

Sydent ermöglicht die Zuordnung (mapping) von Matrix-IDs mit anderen 3rd Party IDs (3PIDs), wie z.B. E-Mail-Adressen oder Telefonnummern, sowie die Verfizierung dieser. Diese Funktionalität schafft Benutzerfreundlichkeit und ermöglicht es Nutzern sich gegenseitig mittels 3PIDs zu erreichen.

Die Matrix.org Foundation arbeitet derzeit noch an einem dezentralen System zur Authentifizierung vertrauenswürdiger Identitäten, zur Überbrückung wird derzeit ein zentralisiertes Cluster von verifizierten Partnern betrieben an welche über https://matrix.org oder https://vector.im angedockt werden kann.

Auch eigene Instanzen können betrieben werden, allerdings mit dem Nachteil andere User über 3PIDS nicht auflösen und schließlich kontaktieren zu können. Für eine Ausgeprägte Infrastruktur könnte dies eine valide option sein, für die gängige Anwendung im Heimserver-Gebrauch wird dies allerdings nicht empfohlen.

Wir haben uns gegen eine eigene Installation aus den genannten Gründen entschieden.

Technische Details

Sydent ist in Python geschrieben und integriert sich nahtlos in die Matrix API. Ferner verwendet Sydent gängige Webtechnologien wie HTTP/HTTPS-basierte Kommunikation für API anfragen und JSON für den Datenaustausch.

Analog zu Synapse, verwendet Sydent eine SQLite Datenbank.

3.2.6. Absicherung eines Matrix-Servers

SSH hardening

Zugriff nur über SSH mit Schlüssel-basierten Anmeldungen erlauben. Standard-Port ändern, um Brute-Force-Angriffe zu verhindern

Firewall

Konfiguration der Firewall, um Datenverkehr zu steuern und unerwünschte Verbindungen zu blockieren

  1. Eingehende HTTPS-Regel für grundlegende Serverfunktionalität:

iptables -A INPUT -p tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT
  1. Ausgehende Regel für HTTPS:

iptables -A OUTPUT -p tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT
  1. Ausgehender Port 8448 für den Zugriff auf Homeserver ohne Reverse Proxy:

iptables -A INPUT -p tcp --dport 8448 -m conntrack --ctstate NEW -j ACCEPT
  1. Regel für etablierte Verbindungen:

iptables -A INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
  1. Loopback-Regel für interne Verbindungen:

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
  1. SSH-Regel:

iptables -A INPUT -p tcp --dport <NEUER SSH-PORT> -m conntrack --ctstate NEW -j ACCEPT

Sicherheitmaßnahmen

Ende-zu-Ende-Verschlüsselung (E2EE): Matrix bietet durch das Olm/Megolm Verschlüsselungsprotokoll eine starke Ende-zu-Ende-Verschlüsselung, die sicherstellt, dass die Kommunikation zwischen den Endpunkten privat bleibt, selbst wenn der Server kompromittiert wird.

Föderation: Synapse ermöglicht Server-Föderation, was bedeutet, dass Nutzer auf verschiedenen Servern miteinander kommunizieren können. Dies erfordert ein sicheres Serverzu-Server-Kommunikationsprotokoll, das ebenfalls TLS verwendet.

Rollenzugriffssteuerung: Matrix unterstützt komplexes Permission-Handling auf Raumbasis, was es Administratoren ermöglicht, sehr fein granulierte Zugriffskontrollrichtlinien zu definieren. Schutz vor Denial-of-Service (DoS)-Angriffen: Mechanismen zur Erkennung und Abwehr von DoS-Angriffen, um Verfügbarkeit und unterbrechungsfreie Dienste aufrechtzuerhalten.

Verschlüsselung der Datenübertragung: Alle Datenübertragungen zwischen den Benutzern und den Servern von Matrix sind verschlüsselt, durch die Verwendung von HTTPS.

Datenschutz durch Dezentralisierung: Matrix ist ein dezentrales Kommunikationsprotokoll, bei dem die Daten auf verschiedenen Servern (Homeservern) verteilt sind. Diese Dezentralisierung trägt dazu bei, dass keine zentrale Stelle alle Daten kontrolliert, was die Sicherheit erhöht.

Zugriffskontrollen: Um sicherzustellen, dass Benutzer nur auf die Informationen zugreifen können, für die sie autorisiert sind. Dies wird durch Berechtigungen und Rollen gesteuert, die von den Administratoren der Räume festgelegt werden.

3.2.7. TURN-Server Sicherheitsanalyse

Authentifizierung und Autorisierung: TURN verwendet eine Authentifizierungsmethode, die typischerweise auf Benutzername und Passwort basiert. Diese Authentifizierungsdaten werden in der Regel durch das Long-Term Credential Mechanism geschützt, der eine Form der DigestAuthentifizierung verwendet.

Verkehrsverschlüsselung: TURN unterstützt die Verschlüsselung des Datenverkehrs mittels TLS (Transport Layer Security), um die Datenintegrität und Vertraulichkeit zu gewährleisten und Manin-the-Middle-Angriffe zu vermeiden.

Datenschutz: Da der TURN Server häufig große Mengen an Daten durchleitet, ist es wichtig, dass keine sensiblen Informationen gespeichert oder ungeschützt übertragen werden.

Potenzielle Sicherheitsrisiken

Missbrauchspotenzial: Ein schlecht gesicherter TURN Server kann von Angreifern als Relais für den Datenverkehr missbraucht werden, was zu Bandbreiten-Diebstahl und unerwünschtem Datenverkehr führen kann. Dies könnte auch den Server für DDoS-Angriffe anfällig machen, indem er als Verstärker genutzt wird.

Spoofing und Replay-Angriffe: Ohne starke Authentifizierungsprotokolle könnten Angreifer versuchen, sich als legitime Nutzer auszugeben oder frühere Authentifizierungsanfragen zu wiederholen, um Zugang zu erlangen.

Schlüsselmanagement: Fehler im Management von Verschlüsselungsschlüsseln und Zertifikaten können dazu führen, dass Verschlüsselungsmaßnahmen unwirksam werden, was die Vertraulichkeit und Integrität der übertragenen Daten gefährdet.

Konfigurationsfehler: Fehlkonfigurationen können dazu führen, dass unbefugte Benutzer Zugriff auf den TURN Server erlangen oder dass der Datenverkehr nicht korrekt verschlüsselt wird.