# Element Web Web-Client für den eigenen Matrix-Server, ausgeliefert als statische Dateien über nginx. | Punkt | Wert | |---|---| | Software | `element-web` (Release-Tarball) | | Öffentlich | `https://element.example.com` | | Verzeichnis | `/var/www/element` | ## Warum eine eigene Domain? Element **darf nicht** unter derselben Domain laufen wie die Client-API des Homeservers. Beide teilen sich sonst denselben Origin, und eine Schwachstelle im Client könnte direkt auf die API zugreifen. Deshalb: - `matrix.example.com` → nur Synapse - `element.example.com` → nur der Web-Client ## 1. Herunterladen und Signatur prüfen ```bash VER=$(curl -s https://api.github.com/repos/element-hq/element-web/releases/latest \ | python3 -c "import json,sys; print(json.load(sys.stdin)['tag_name'])") echo "$VER" curl -fLO "https://github.com/element-hq/element-web/releases/download/${VER}/element-${VER}.tar.gz" curl -fLO "https://github.com/element-hq/element-web/releases/download/${VER}/element-${VER}.tar.gz.asc" ``` Die Signatur zu prüfen ist hier keine Formsache: das Paket läuft später im Browser mit vollem Zugriff auf die Sitzung. ```bash curl -fsSL -o element-release-key.gpg https://packages.element.io/element-release-key.gpg gpg --import element-release-key.gpg gpg --verify element-${VER}.tar.gz.asc element-${VER}.tar.gz ``` Erwartet wird `Good signature from "Element Releases "` mit dem Fingerprint `712B FBEE 92DC A452 52DB 17D7 C7BE 97EF A179 B100`. Die Meldung „This key is not certified with a trusted signature“ ist dabei normal – sie besagt nur, dass der Schlüssel lokal nicht als vertrauenswürdig markiert wurde. Entscheidend ist, dass der Fingerprint stimmt. ## 2. Ausrollen ```bash sudo tar xzf element-${VER}.tar.gz -C /var/www sudo rm -rf /var/www/element sudo mv /var/www/element-${VER} /var/www/element sudo chown -R www-data:www-data /var/www/element ``` ## 3. Konfiguration `config.json.example` nach `/var/www/element/config.json` kopieren und anpassen. Wichtig ist der Unterschied der beiden Felder: - `base_url` → wo die API tatsächlich liegt (`https://matrix.example.com`) - `server_name` → was dem Benutzer angezeigt wird (`example.com`) ```json { "default_server_config": { "m.homeserver": { "base_url": "https://matrix.example.com", "server_name": "example.com" } }, "disable_guests": true } ``` ## 4. nginx `nginx/element.example.com.conf` und `nginx/element-security.conf` kopieren: ```bash sudo cp nginx/element-security.conf /etc/nginx/snippets/ sudo cp nginx/element.example.com.conf /etc/nginx/sites-available/ sudo ln -s /etc/nginx/sites-available/element.example.com.conf /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx ``` ### Zwei Fallstricke in der nginx-Konfiguration **Caching.** `index.html`, `config.json` und `version` dürfen nicht dauerhaft gecacht werden. Sonst zeigt der Browser nach einem Update weiter die alte Version oder alte Serverdaten. Die Dateien unter `/bundles/` tragen dagegen einen Hash im Namen und dürfen unbegrenzt gecacht werden. **Header-Vererbung.** nginx vererbt `add_header` **nicht**, sobald ein `location`-Block eigene `add_header`-Direktiven enthält. Da `location /` per `try_files` auf `/index.html` verweist und dieser Block ein eigenes `Cache-Control` setzt, würden die Sicherheitsheader dort stillschweigend verschwinden. Deshalb liegen sie in einem Snippet, das in **jedem** betroffenen Block eingebunden wird. Kontrolle: ```bash curl -s -o /dev/null -D - https://element.example.com/ | grep -iE '^x-|^strict|^referrer' ``` Es müssen `x-frame-options`, `x-content-type-options`, `referrer-policy` und `strict-transport-security` auftauchen. ## 5. Prüfung ```bash curl -s -o /dev/null -w "%{http_code}\n" https://element.example.com/ curl -s https://element.example.com/version curl -s https://element.example.com/config.json ``` Danach im Browser öffnen und mit einem Konto anmelden. Der Anmeldedialog sollte `example.com` als Server anzeigen, nicht `matrix.example.com`. ## Aktualisieren Element ist rein statisch – ein Update ist ein Austausch des Verzeichnisses. Die `config.json` liegt im Verzeichnis und muss dabei gesichert werden: ```bash sudo cp /var/www/element/config.json /tmp/element-config.json # ... neue Version wie oben entpacken ... sudo cp /tmp/element-config.json /var/www/element/config.json sudo chown -R www-data:www-data /var/www/element ``` ## Stolpersteine | Symptom | Ursache | |---|---| | Nach Update alte Version im Browser | `index.html`/`version` wurden gecacht | | Sicherheitsheader fehlen | `add_header`-Vererbung durch eigenen `location`-Block gekippt | | Anmeldung zeigt falschen Servernamen | `server_name` in `config.json` falsch | | Konfiguration nach Update weg | `config.json` liegt im ausgetauschten Verzeichnis |