WOPI
WOPI — Funktionsweise und Fallstricke
WOPI (Web Application Open Platform Interface) ist ein Protokoll das Microsoft 2013 für Office Online entwickelt hat. Es ermöglicht Browser-basierten Office-Editoren wie Collabora Online oder Microsoft Office Online, Dokumente von einem externen Speicherort zu öffnen, zu bearbeiten und zu speichern — ohne das Dokument vollständig herunterzuladen.
Nextcloud und Collabora nutzen WOPI weil es das einzige offene Protokoll ist das diese Aufgabe beschreibt. Es wurde jedoch nie für selbst-gehostete Docker-Setups hinter Reverse Proxies konzipiert — was die Konfiguration entsprechend fragil macht.
Wie WOPI funktioniert
Der Ablauf beim Öffnen eines Dokuments in drei Schritten:
Schritt 1: Discovery (intern)
Nextcloud fragt Collabora: „Welche Dateiformate kannst du öffnen?"
Nextcloud → GET https://collabora.beispiel.de/hosting/discovery Collabora → XML mit allen unterstützten MIME-Types und Endpunkten
Dieser Schritt läuft intern — Container zu Container, über das Docker-Netzwerk.
Nie über die externe IP, wenn extra_hosts korrekt konfiguriert ist.
Schritt 2: Token-Generierung (intern)
Der Nutzer klickt auf ein Dokument. Nextcloud generiert einen zeitlich begrenzten WOPI-Token und baut eine URL zusammen:
https://collabora.beispiel.de/browser/...? WOPISrc=https://nextcloud.beispiel.de/index.php/apps/richdocuments/wopi/files/123 &access_token=abc123xyz
Diese URL schickt Nextcloud an den Browser des Nutzers.
Schritt 3: Rendering (extern)
Der Browser öffnet Collabora direkt mit dieser URL. Collabora holt das Dokument von Nextcloud:
Collabora → GET https://nextcloud.beispiel.de/.../wopi/files/123 (CheckFileInfo) Collabora → GET https://nextcloud.beispiel.de/.../wopi/files/123/contents (GetFile) Nextcloud → prüft Token, liefert Dokument Collabora → rendert Dokument im Browser
Dieser Schritt läuft extern — der Browser spricht Collabora direkt an, Collabora spricht Nextcloud direkt an. Beide Wege müssen funktionieren.
Das Dilemma der zwei Wege
Schritt 1 muss intern funktionieren (sonst: 403 oder Timeout).
Schritt 3 muss extern funktionieren (sonst: „Unautorisierter WOPI-Host").
In einer Cloud-Umgebung mit festen IPs und direkten Verbindungen ist das kein Problem. Hinter einem Reverse Proxy im Heimnetz mit dynamischen Container-IPs und Hairpinning: eine häufige Fehlerquelle.
Siehe dazu: Hairpin-NAT – Collabora und Nextcloud hinter Caddy
/hosting/discovery — das Information-Disclosure-Problem
/hosting/discovery ist der Endpunkt aus Schritt 1. Er ist bewusst
öffentlich designed — Collabora muss sich hier vorstellen damit der Client weiß
welche Dateiformate unterstützt werden.
Ein einfacher Aufruf von außen liefert jedoch eine ausführliche Antwort:
<syntaxhighlight lang="bash"> curl https://collabora.beispiel.de/hosting/discovery </syntaxhighlight>
Die Antwort enthält:
- Collabora-Version und Build-Nummer
- Alle unterstützten MIME-Types
- Interne Pfadstrukturen
- Capability-Flags
Für einen Angreifer ist das eine Einladung: bekannte Version → bekannte CVEs. Das nennt sich Information Disclosure — kein direkter Angriff, aber wertvolle Vorbereitung für einen.
Warum der Endpunkt nicht einfach gesperrt werden kann
/hosting/discovery wird nicht nur von Nextcloud intern aufgerufen —
auch der Browser des Nutzers ruft ihn beim Öffnen eines Dokuments direkt auf.
Eine vollständige Sperre bricht die Funktionalität.
Ein Referer-Check (nur Anfragen von der Nextcloud-Domain durchlassen) ist
theoretisch möglich, aber in der Praxis fehleranfällig: nicht alle Browser
schicken den Referer-Header zuverlässig, und nach einem docker restart caddy
kann ein gecachter alter Stand die Regel temporär außer Kraft setzen.
Pragmatische Absicherung
Den Endpunkt offen lassen, aber die Angriffsfläche auf das funktional notwendige
Minimum reduzieren. In Caddy: nur explizit erlaubte Pfade durchlassen,
alles andere mit 403 ablehnen:
<syntaxhighlight lang="caddy"> collabora.beispiel.de {
@allowed path /browser/* /hosting/capabilities /hosting/discovery /cool/* /lool/*
handle @allowed {
reverse_proxy collabora:9980
}
handle {
respond 403
}
} </syntaxhighlight>
Damit ist die Angriffsfläche auf das funktional notwendige Minimum reduziert — niemand kann beliebige interne Endpunkte von Collabora ansprechen.
Die eigentliche Gegenmaßnahme
Information Disclosure ist kein direkter Angriff — es erleichtert nur die Vorbereitung. Eine aktuelle Collabora-Version ohne bekannte CVEs entzieht dieser Information ihren praktischen Wert.
Wichtiger als der Referer-Check: Collabora aktuell halten.
WOPI-Allowlist — warum sie existiert
Nextcloud prüft bei jedem WOPI-Aufruf ob die anfragende IP in der Allowlist steht. Das verhindert dass ein beliebiger Server vorgeben kann, Collabora zu sein, und auf Dokumente zugreift.
<syntaxhighlight lang="bash">
- Aktuellen Wert prüfen
docker exec nextcloud occ config:app:get richdocuments wopi_allowlist
- Gesamtes Docker-Subnetz erlauben (empfohlen)
docker exec nextcloud occ config:app:set richdocuments wopi_allowlist \
--value="172.18.0.0/16"
</syntaxhighlight>
Das gesamte Docker-Subnetz statt einer einzelnen IP eintragen — dann ist die Allowlist unabhängig von IP-Verschiebungen einzelner Container nach einem Neustart.
Häufige Fehlermeldungen und ihre Ursachen
| Fehlermeldung | Ursache | Fix |
|---|---|---|
| „Unautorisierter WOPI-Host" | Collabora-IP nicht in Nextcloud-Allowlist | WOPI-Allowlist auf Docker-Subnetz setzen |
403 Forbidden bei discovery |
Caddy-Regel blockiert Nextcloud | extra_hosts prüfen, Caddy neu starten
|
| „Failed to connect to remote server" | Nextcloud erreicht Collabora extern statt intern | extra_hosts in Nextcloud-compose korrigieren
|
| Dokument wird heruntergeladen statt geöffnet | Collabora-MIME-Types nicht registriert | occ richdocuments:activate-config ausführen
|
| Admin-Test rot, Dokumente funktionieren | Browser schickt keinen Referer | Normal — Admin-Test ist kein verlässlicher Funktionstest |
Warum der Admin-Test lügt
Der Verbindungstest in den Nextcloud-Einstellungen unter Office → Verbindung testen läuft vom Browser des Administrators aus — nicht vom Nextcloud-Container.
Das bedeutet: die Anfrage kommt von der IP des Administrators (z.B.
192.168.1.42), nicht von der internen Container-IP. Wenn eine
Caddy-Regel nur interne IPs durchlässt, bekommt der Admin-Test 403 —
auch wenn alles korrekt konfiguriert ist.
Der verlässliche Test:
<syntaxhighlight lang="bash"> docker exec nextcloud curl -sk -o /dev/null -w "%{http_code}" \
https://collabora.beispiel.de/hosting/discovery
</syntaxhighlight>
Und direkt ein .docx in Nextcloud öffnen.
Siehe auch
- Hairpin-NAT – Collabora und Nextcloud hinter Caddy — das Netzwerkproblem hinter WOPI
- Docker-Netzwerke und Container-IPs — Konfiguration und Fallstricke — IP-Pinning, extra_hosts, Backup-Checkliste
- Caddy – Konzepte und Konfiguration — Reverse Proxy, Matcher, Firewall-Regeln
Microsoft hat WOPI für SharePoint gebaut. Nextcloud hat es für alle übernommen. Die Konfigurationskomplexität ist das Erbe dieser Entscheidung.
