Files
homelab/services/matrix-synapse/README.md
T
x3 4a55944aa8 Homelab-Dokumentation und Konfigurationsvorlagen
Dokumentation aus dem Wiki uebernommen und um die Dienste auf dem Server
erweitert. Alle Anleitungen sind so geschrieben, dass sich der jeweilige
Dienst allein daraus neu aufsetzen laesst.

docs/      Dienste im Heimnetz (aus dem Wiki, anonymisiert)
services/  Dienste auf dem Server mit Konfigurationsvorlagen
           - matrix-synapse: Homeserver, Postgres, Well-Known-Delegation
           - coturn:         TURN-Relay fuer Anrufe
           - element-web:    Web-Client
           - wikijs, gitea, nginx

Durchgehend anonymisiert: echte Domain durch example.com ersetzt, IP-Adressen
und E-Mail-Adressen durch Platzhalter. Konfigurationsdateien liegen nur als
.example mit Platzhaltern statt echter Secrets vor.

Die Anleitungen halten die Stolpersteine fest, die beim Aufbau tatsaechlich
aufgetreten sind, unter anderem:
- Synapse verlangt LC_COLLATE=C, sonst startet es nicht
- server_name ist nachtraeglich nicht aenderbar -> Delegation noetig
- register_new_matrix_user liest conf.d nicht, Secret muss per -k kommen
- coturn braucht external-ip, sonst kommen keine Medien durch
- Gruppenmitgliedschaft fuer den Zertifikatszugriff wirkt erst beim Neustart
- nginx vererbt add_header nicht in location-Bloecke mit eigenen Direktiven
2026-08-31 17:56:02 +00:00

271 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Matrix-Homeserver (Synapse)
Eigener Matrix-Server mit PostgreSQL, nginx als TLS-Terminierung und
Well-Known-Delegation, damit die Benutzer-IDs kurz bleiben.
| Punkt | Wert |
|---|---|
| Software | Synapse (Paket `matrix-synapse-py3` von packages.matrix.org) |
| Datenbank | PostgreSQL |
| Interner Listener | `127.0.0.1:8008` (kein TLS, das macht nginx) |
| Öffentlich | `https://matrix.example.com` |
| Benutzer-IDs | `@name:example.com` |
## Warum zwei Domains?
Das ist der Punkt, an dem die meisten Anleitungen unnötig kompliziert werden.
Der `server_name` ist der **hintere Teil jeder Benutzer-ID**. Setzt man ihn auf
`matrix.example.com`, heißen alle Benutzer `@name:matrix.example.com` unschön
und nicht mehr änderbar, denn der `server_name` lässt sich nachträglich **nicht**
umstellen, ohne alle Konten und Räume zu verlieren.
Deshalb:
- `server_name: example.com` → IDs lauten `@name:example.com`
- Synapse läuft aber auf `matrix.example.com`
- Zwei kleine JSON-Dokumente unter `https://example.com/.well-known/matrix/…`
verweisen andere Server und Clients dorthin
Die Apex-Domain muss dafür **nur diese zwei Dateien** ausliefern, sonst nichts.
## Voraussetzungen
- Debian/Ubuntu mit root-Rechten
- PostgreSQL
- nginx
- certbot
- DNS-A-Records auf den Server: `example.com`, `matrix.example.com`
## 1. Paketquelle und Installation
```bash
sudo install -d -m 0755 /etc/apt/keyrings
sudo curl -fsSL -o /etc/apt/keyrings/matrix-org-archive-keyring.gpg \
https://packages.matrix.org/debian/matrix-org-archive-keyring.gpg
# <suite> ist der Codename der Distribution, z. B. noble, trixie, resolute
echo "deb [signed-by=/etc/apt/keyrings/matrix-org-archive-keyring.gpg] \
https://packages.matrix.org/debian/ <suite> main" \
| sudo tee /etc/apt/sources.list.d/matrix-org.list
sudo apt-get update
```
Ob es für die eigene Distribution ein Paket gibt, lässt sich vorher prüfen:
```bash
curl -s https://packages.matrix.org/debian/dists/<suite>/main/binary-amd64/Packages \
| grep -E "^Package:|^Version:"
```
Installation. Der `server_name` wird per debconf vorbelegt, damit die
Installation nicht interaktiv nachfragt:
```bash
echo "matrix-synapse-py3 matrix-synapse/server-name string example.com" \
| sudo debconf-set-selections
echo "matrix-synapse-py3 matrix-synapse/report-stats boolean false" \
| sudo debconf-set-selections
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y matrix-synapse-py3
```
> **Wichtig:** Der hier gesetzte `server_name` ist endgültig. Er landet in
> `/etc/matrix-synapse/conf.d/server_name.yaml`.
## 2. Datenbank
Synapse besteht auf `C`-Collation. Eine mit den üblichen `de_DE.UTF-8`-Vorgaben
angelegte Datenbank wird beim Start **abgelehnt**:
```bash
sudo -u postgres psql <<'SQL'
CREATE ROLE synapse_user LOGIN PASSWORD 'HIER-EIN-STARKES-PASSWORT';
CREATE DATABASE synapse
ENCODING 'UTF8'
LC_COLLATE='C'
LC_CTYPE='C'
template=template0
OWNER synapse_user;
SQL
```
Kontrolle unter `Collate`/`Ctype` muss `C` stehen:
```bash
sudo -u postgres psql -c "\l synapse"
```
## 3. Konfiguration
Eigene Einstellungen gehören nach `/etc/matrix-synapse/conf.d/`. Die
`homeserver.yaml` wird vom Paket verwaltet und bei Upgrades überschrieben.
Der von der Installation angelegte SQLite-Block in `homeserver.yaml` muss
entfernt oder auskommentiert werden, sonst kollidiert er mit der conf.d-Datei:
```bash
sudo sed -i '/^database:/,/database: \/var\/lib\/matrix-synapse\/homeserver.db/d' \
/etc/matrix-synapse/homeserver.yaml
```
Dann die Vorlagen aus diesem Verzeichnis kopieren und die Platzhalter füllen:
```bash
sudo cp conf.d/database.yaml.example /etc/matrix-synapse/conf.d/database.yaml
sudo cp conf.d/homelab.yaml.example /etc/matrix-synapse/conf.d/homelab.yaml
sudo chown root:matrix-synapse /etc/matrix-synapse/conf.d/*.yaml
sudo chmod 640 /etc/matrix-synapse/conf.d/*.yaml
```
### Secrets explizit setzen
Fehlen `macaroon_secret_key` und `form_secret`, leitet Synapse sie aus dem
Signing-Key ab und warnt beim Start. Wird der Signing-Key später ersetzt, sind
schlagartig **alle Access-Tokens ungültig**. Deshalb einmalig festlegen:
```bash
sudo tee /etc/matrix-synapse/conf.d/secrets.yaml >/dev/null <<EOF
macaroon_secret_key: "$(openssl rand -base64 48 | tr -d '\n')"
form_secret: "$(openssl rand -base64 48 | tr -d '\n')"
EOF
sudo chown root:matrix-synapse /etc/matrix-synapse/conf.d/secrets.yaml
sudo chmod 640 /etc/matrix-synapse/conf.d/secrets.yaml
```
Registrierungs-Secret separat ablegen, damit es nicht in einer YAML steht:
```bash
openssl rand -hex 32 | sudo tee /etc/matrix-synapse/registration_shared_secret >/dev/null
sudo chown root:matrix-synapse /etc/matrix-synapse/registration_shared_secret
sudo chmod 640 /etc/matrix-synapse/registration_shared_secret
```
Start:
```bash
sudo systemctl restart matrix-synapse
sudo systemctl status matrix-synapse
curl -s http://127.0.0.1:8008/_matrix/client/versions
```
## 4. nginx
`nginx/matrix.conf` nach `/etc/nginx/sites-available/` kopieren, verlinken und
ein Zertifikat holen:
```bash
sudo certbot certonly --webroot -w /var/www/html -d matrix.example.com
sudo ln -s /etc/nginx/sites-available/matrix.example.com \
/etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
```
Zwei Details in der Konfiguration sind nicht optional:
- `client_max_body_size` muss mindestens so groß sein wie `max_upload_size` in
Synapse, sonst brechen Uploads mit einem nginx-413 ab, bevor Synapse sie sieht.
- `proxy_read_timeout` muss großzügig sein. Clients halten `/sync` als
Long-Poll offen; beim nginx-Standard von 60 Sekunden reißt die Verbindung
ständig ab.
## 5. Well-Known-Delegation
Im vHost der **Apex-Domain** (`example.com`):
```nginx
location = /.well-known/matrix/server {
default_type application/json;
add_header Access-Control-Allow-Origin *;
return 200 '{"m.server": "matrix.example.com:443"}';
}
location = /.well-known/matrix/client {
default_type application/json;
add_header Access-Control-Allow-Origin *;
return 200 '{"m.homeserver": {"base_url": "https://matrix.example.com"}}';
}
```
Der `Access-Control-Allow-Origin`-Header ist beim Client-Dokument
zwingend ohne ihn verweigern Browser-Clients die Abfrage.
Prüfen:
```bash
curl -s https://example.com/.well-known/matrix/server
curl -s https://example.com/.well-known/matrix/client
```
## 6. Admin-Benutzer anlegen
Die Registrierung ist bewusst geschlossen (`enable_registration: false`), sonst
wird der Server binnen Tagen als Spam-Relay missbraucht. Benutzer werden per
Shared Secret angelegt.
`register_new_matrix_user` liest **nur** die mit `-c` übergebene Datei. Liegt
das Secret in `conf.d/`, findet es der Befehl nicht deshalb direkt übergeben:
```bash
SECRET=$(sudo cat /etc/matrix-synapse/registration_shared_secret)
sudo register_new_matrix_user -k "$SECRET" \
-u admin -p 'PASSWORT' -a http://127.0.0.1:8008
```
`-a` macht den Benutzer zum Server-Admin. Kontrolle:
```bash
sudo -u postgres psql -d synapse -c "SELECT name, admin FROM users;"
```
## 7. Funktionsprüfung
```bash
# Login über die öffentliche URL
curl -s -X POST https://matrix.example.com/_matrix/client/v3/login \
-H 'Content-Type: application/json' \
-d '{"type":"m.login.password",
"identifier":{"type":"m.id.user","user":"admin"},
"password":"PASSWORT"}'
# Föderation von außen prüfen (offizieller Tester)
curl -s "https://federationtester.matrix.org/api/report?server_name=example.com" \
| python3 -c "import json,sys; print('FederationOK:', json.load(sys.stdin)['FederationOK'])"
```
`FederationOK: True` ist das Ziel. Schlägt es fehl, liegt es fast immer an der
Well-Known-Datei oder an einer unvollständigen Zertifikatskette.
## Betrieb
```bash
sudo systemctl status matrix-synapse
sudo journalctl -u matrix-synapse -f
```
Datenbank sichern:
```bash
sudo -u postgres pg_dump -Fc synapse > synapse-$(date +%F).dump
```
Mitzusichern sind außerdem:
- `/etc/matrix-synapse/homeserver.signing.key` **ohne diesen Schlüssel ist der
Server für andere Server eine andere Identität.** Nicht ersetzbar.
- `/etc/matrix-synapse/conf.d/` enthält die Secrets
- `/var/lib/matrix-synapse/media` hochgeladene Dateien
## Stolpersteine
| Symptom | Ursache |
|---|---|
| Start bricht mit Collation-Fehler ab | Datenbank ohne `LC_COLLATE='C'` angelegt |
| „Config is missing macaroon_secret_key“ | `secrets.yaml` fehlt |
| Uploads scheitern mit 413 | `client_max_body_size` < `max_upload_size` |
| Clients verlieren dauernd die Verbindung | `proxy_read_timeout` zu klein |
| Föderation schlägt fehl | Well-Known falsch oder Zertifikatskette unvollständig |
| IDs lauten `@name:matrix.example.com` | `server_name` falsch gesetzt nicht mehr korrigierbar |