Was ist XMPP?

XMPP (Extensible Messaging and Presence Protocol) ist ein offenes, dezentrales Kommunikationsprotokoll. Im Gegensatz zu WhatsApp, Signal oder Telegram betreibst du deinen eigenen Server und behältst die volle Kontrolle über deine Daten. XMPP nutzt eine föderierte Architektur – ähnlich wie E-Mail –, sodass Nutzer verschiedener Server problemlos miteinander kommunizieren können.

Was ist OMEMO?

OMEMO (OMEMO Multi-End Message and Object Encryption) ist eine Ende-zu-Ende-Verschlüsselung für XMPP, die auf dem Signal-Protokoll (Double Ratchet) basiert. Im Unterschied zu OTR unterstützt OMEMO mehrere Geräte gleichzeitig und verschlüsselt auch Dateien. Der Server sieht dabei nur verschlüsselte Daten – selbst als Admin kannst du keine Nachrichten mitlesen.

OMEMO benötigt auf dem Server kein spezielles Modul, sondern setzt auf PEP (Personal Eventing Protocol) und PubSub, um die öffentlichen Schlüssel der Geräte zu verteilen. Diese Module müssen korrekt konfiguriert sein.

Prosody installieren

Wir verwenden Prosody als XMPP-Server. Prosody ist leichtgewichtig, modular und hervorragend dokumentiert. Auf Debian oder Ubuntu installierst du zuerst das offizielle Repository, um die neueste Version zu erhalten:

sudo apt install apt-transport-https
echo "deb https://packages.prosody.im/debian $(lsb_release -cs) main" | \
  sudo tee /etc/apt/sources.list.d/prosody.list
curl -fsSL https://prosody.im/files/prosody-debian-packages.key | \
  sudo tee /etc/apt/trusted.gpg.d/prosody.asc
sudo apt update
sudo apt install prosody prosody-modules

Das Paket prosody-modules enthält die Community-Module, die wir für HTTP-Upload und andere Features brauchen.

TLS-Zertifikate einrichten

Verschlüsselung beginnt auf der Transportebene. Ohne gültiges TLS-Zertifikat verweigern die meisten Clients und anderen Server die Verbindung. Am einfachsten geht das mit Let's Encrypt:

sudo apt install certbot
sudo certbot certonly --standalone -d xmpp.example.com \
  -d conference.xmpp.example.com \
  -d upload.xmpp.example.com

Anschließend importierst du die Zertifikate in Prosody:

sudo prosodyctl --root cert import /etc/letsencrypt/live/

Richte einen Cronjob oder systemd-Timer ein, der nach der Erneuerung automatisch prosodyctl cert import und prosodyctl reload ausführt.

PEP und PubSub für OMEMO aktivieren

Öffne die Hauptkonfiguration unter /etc/prosody/prosody.cfg.lua und stelle sicher, dass folgende Module geladen werden:

modules_enabled = {
    -- Core
    "roster";
    "saslauth";
    "tls";
    "dialback";
    "disco";

    -- OMEMO-relevante Module
    "pep";
    "pep_simple";
    "pubsub";

    -- Nützliche Erweiterungen
    "carbons";        -- Nachrichten an alle Geräte
    "mam";            -- Nachrichtenarchiv
    "smacks";         -- Stream Management
    "csi_simple";     -- Client State Indication
    "cloud_notify";   -- Push-Benachrichtigungen
    "http_upload";    -- Datei-Upload
    "blocklist";
    "bookmarks";
    "vcard_legacy";
}

Wichtig: Das Modul pep ist zwingend erforderlich. Ohne PEP kann kein Client seine OMEMO-Schlüssel veröffentlichen, und die Verschlüsselung schlägt fehl.

HTTP File Upload für verschlüsselte Medien

OMEMO verschlüsselt nicht nur Text, sondern auch Bilder, Videos und Dateien. Dafür müssen die verschlüsselten Dateien über HTTP Upload (XEP-0363) hochgeladen werden. Konfiguriere eine eigene Subdomain:

Component "upload.xmpp.example.com" "http_upload"
    http_upload_file_size_limit = 104857600  -- 100 MB
    http_upload_expire_after = 60 * 60 * 24 * 30  -- 30 Tage
    http_upload_quota = 1073741824  -- 1 GB pro Nutzer
    http_external_url = "https://upload.xmpp.example.com/"

Falls du einen Reverse Proxy wie nginx nutzt, leite den Traffic entsprechend weiter:

server {
    listen 443 ssl http2;
    server_name upload.xmpp.example.com;

    ssl_certificate /etc/letsencrypt/live/upload.xmpp.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/upload.xmpp.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:5281/upload/;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        client_max_body_size 105m;
    }
}

MAM (Message Archive Management) konfigurieren

MAM (XEP-0313) speichert Nachrichten serverseitig, damit du sie auf neuen Geräten abrufen kannst. Bei OMEMO werden nur die verschlüsselten Daten archiviert – der Server kann den Inhalt nicht lesen.

archive_expires_after = "4w"  -- Nachrichten nach 4 Wochen löschen
default_archive_policy = true  -- MAM standardmäßig aktiviert

-- Für den VirtualHost:
VirtualHost "xmpp.example.com"
    ssl = {
        key = "/etc/prosody/certs/xmpp.example.com.key";
        certificate = "/etc/prosody/certs/xmpp.example.com.crt";
    }

Component "conference.xmpp.example.com" "muc"
    modules_enabled = { "muc_mam"; }
    muc_log_by_default = true
    muc_log_expires_after = "4w"

Benutzer anlegen und Server starten

sudo prosodyctl register alice xmpp.example.com sicheres-passwort
sudo prosodyctl register bob xmpp.example.com anderes-passwort
sudo systemctl enable --now prosody
sudo prosodyctl status

Prüfe, ob alle Module geladen wurden:

sudo prosodyctl about

Empfohlene Clients

Nicht jeder XMPP-Client unterstützt OMEMO. Hier sind die besten Optionen je nach Plattform:

  • Conversations (Android) – Der Goldstandard. OMEMO ist standardmäßig aktiviert, unterstützt Datei-Upload, Audio-/Videoanrufe und Push-Benachrichtigungen.
  • Gajim (Windows/Linux) – Feature-reicher Desktop-Client. Das OMEMO-Plugin muss über den Plugin-Manager installiert werden.
  • Dino (Linux) – Moderner, schlanker GTK-Client mit nativer OMEMO-Unterstützung. Ideal für GNOME-Nutzer.
  • Siskin IM (iOS) – Von den Tigase-Entwicklern, gute OMEMO-Integration und Push-Support für Apple-Geräte.

OMEMO-Schlüsselaustausch testen

Nach der Anmeldung mit einem Client sollte OMEMO automatisch eingerichtet werden. Um den Schlüsselaustausch zu verifizieren:

  1. Melde dich mit zwei Accounts an (z.B. Alice in Conversations, Bob in Dino).
  2. Alice sendet eine Nachricht an Bob. Der Client sollte ein Schloss-Symbol anzeigen.
  3. Überprüfe in den Account-Einstellungen die OMEMO-Fingerprints. Beide Seiten sollten den Fingerprint des Gegenübers sehen.
  4. Verifiziere die Fingerprints über einen sicheren Kanal (persönlich, QR-Code oder Telefonat).

Falls der Schlüsselaustausch nicht funktioniert, überprüfe mit dem folgenden Befehl, ob PEP korrekt publiziert:

# Prüfe, ob OMEMO-Daten im PEP-Knoten vorhanden sind:
sudo prosodyctl shell
> host = prosody.hosts["xmpp.example.com"]
> for node in host.modules.pep.get_account_service("alice"):nodes() do print(node) end

In der Ausgabe solltest du Knoten wie eu.siacs.conversations.axolotl.devicelist und eu.siacs.conversations.axolotl.bundles:<device-id> sehen.

Fehlerbehebung und häufige Probleme

OMEMO wird im Client nicht angeboten

Stelle sicher, dass mod_pep geladen ist. Prüfe die Logs unter /var/log/prosody/prosody.log auf Fehler. Ein häufiger Grund: Das Modul pep_simple fehlt oder wird von einem veralteten pep_plus blockiert.

Datei-Upload schlägt fehl

Überprüfe, ob die Upload-Komponente korrekt erreichbar ist:

curl -I https://upload.xmpp.example.com/

Häufige Ursachen: Fehlende CORS-Header, falscher http_external_url, oder die Firewall blockiert Port 5281.

Nachrichten kommen nicht auf allen Geräten an

Aktiviere mod_carbons und mod_smacks. Carbons sorgt dafür, dass Nachrichten an alle angemeldeten Geräte kopiert werden. Ohne Stream Management (smacks) gehen Nachrichten bei instabilen Verbindungen verloren.

Verbindungsprobleme mit anderen Servern

Stelle sicher, dass deine DNS-Einträge korrekt gesetzt sind:

_xmpp-client._tcp.xmpp.example.com. 3600 IN SRV 0 5 5222 xmpp.example.com.
_xmpp-server._tcp.xmpp.example.com. 3600 IN SRV 0 5 5269 xmpp.example.com.

Teste die Federation mit dem XMPP Compliance Tester. Dieser prüft alle relevanten XEPs und zeigt dir, wo dein Server noch Lücken hat.

Tipp: Führe regelmäßig sudo apt update && sudo apt upgrade prosody prosody-modules aus. Sicherheitslücken in XMPP-Servern werden schnell ausgenutzt, und veraltete Module können die Verschlüsselung kompromittieren.