Zwölf Builds

Ein Matrix-Homeserver, dessen Föderation tatsächlich funktioniert

Synapse auf einer kleinen Ryzen-Instanz mit Postgres, Delegation über Well-known-Dateien statt SRV-Einträgen und Verifikation, die andere Server erreicht.

Was damit entsteht

Ein Heimserver unter example.com, der auf matrix.example.com läuft und mit allen anderen korrekt föderiert. Postgres darunter, nginx davor, Delegation über zwei kleine JSON-Dateien, Registrierung geschlossen, damit Ihr Server nicht innerhalb einer Woche zu einem kostenlosen Relay für Fremde wird.

Föderation ist der Punkt, an dem diese Installationen normalerweise scheitern, und fast nie an Synapse. Der Server läuft, lokale Nachrichten funktionieren, und dann kommt nichts von außen an. In der Praxis liegt die Ursache fast immer an der Delegation: Die Identität des Servers und die Adresse, unter der er erreichbar ist, sind zwei verschiedene Dinge, und der Mechanismus, der sie verbindet, kann auf subtile Weise falsch konfiguriert sein.

Bevor Sie beginnen

  • Ein R-4 reicht für ein paar Dutzend Benutzer. Synapse braucht eher viel Arbeitsspeicher als CPU-Leistung, und das Beitreten zu großen föderierten Räumen ist die einzige Sache, die ihm wirklich zusetzt.
  • Zwei Namen in DNS: example.com, das die Identität Ihres Servers ist und in jeder Benutzer-ID erscheint, und matrix.example.com, wo die Software tatsächlich lauscht.
  • Zertifikate für beide. Das erste muss nur zwei statische Dateien ausliefern.

1. Datenbank mit der richtigen Kollation

apt update && apt install -y postgresql matrix-synapse nginx certbot
sudo -u postgres psql -c "CREATE USER synapse_user WITH PASSWORD '<a long password>';"
sudo -u postgres psql -c "CREATE DATABASE synapse ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' TEMPLATE=template0 OWNER synapse_user;"

Die Kollation ist kein Detail. Synapse weigert sich, auf einer Datenbank zu starten, die mit einer anderen Kollation als C erstellt wurde, und der Fehler, den es ausgibt, wenn Sie das falsch machen, erscheint, nachdem Sie bereits Daten importiert haben. Machen Sie es jetzt richtig, einmalig.

2. Homeserver-Konfiguration

Das Debian-Paket fragt während der Installation nach dem Servernamen; antworten Sie example.com, nicht den Hostnamen der Maschine. Diese Antwort wird Teil jeder Benutzer-ID und Raum-ID auf dem Server und kann später nicht geändert werden, ohne den Server aufzugeben.

Dann bearbeiten Sie /etc/matrix-synapse/homeserver.yaml:

server_name: "example.com"
public_baseurl: "https://matrix.example.com/"
pid_file: /run/matrix-synapse.pid

listeners:
  - port: 8008
    tls: false
    type: http
    x_forwarded: true
    bind_addresses: ['127.0.0.1']
    resources:
      - names: [client, federation]
        compress: false

database:
  name: psycopg2
  args:
    user: synapse_user
    password: "<a long password>"
    database: synapse
    host: 127.0.0.1
    cp_min: 5
    cp_max: 10

enable_registration: false
registration_shared_secret: "<a long random string>"
report_stats: false
suppress_key_server_warning: true
url_preview_enabled: false

media_store_path: /var/lib/matrix-synapse/media
max_upload_size: 100M
media_retention:
  remote_media_lifetime: 30d

rc_message:
  per_second: 0.5
  burst_count: 15

Zwei dieser Einstellungen sparen Ihnen Speicherplatz und Ärger. Remote-Media-Aufbewahrung verwirft zwischengespeicherte Kopien von Dateien anderer Server nach einem Monat, und ohne sie wächst Ihr Medienbestand endlos mit Inhalten, die Sie nie angefordert haben. URL-Vorschauen sind deaktiviert, weil Ihr Server dadurch willkürliche Adressen im Auftrag von jedem abruft, der einen Link posten kann – das ist eine Request-Forgery-Engine mit angeschlossener Chat-Oberfläche.

x_forwarded: true ist ebenfalls wichtig: Ohne sie drosselt Synapse jeden Benutzer der Welt, als wären sie ein einziger Client, weil jede Anfrage scheinbar von nginx kommt.

3. Delegation

Ihre Identität ist example.com und Ihr Server ist unter matrix.example.com. Zwei Dateien überbrücken die Lücke. Servieren Sie sie von example.com aus, über HTTPS, mit dem richtigen Content-Type.

/.well-known/matrix/server:

{ "m.server": "matrix.example.com:443" }

/.well-known/matrix/client:

{ "m.homeserver": { "base_url": "https://matrix.example.com" } }

Der Port in der ersten Datei ist Pflicht. Lassen Sie ihn weg, fallen andere Server auf Port 8448 zurück, finden dort nichts Lauschendes und geben still auf; Ihre Benutzer melden dann, dass die Föderation kaputt ist, während jedes Log auf Ihrer Maschine gesund aussieht.

server {
  listen 443 ssl;
  server_name example.com;
  ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

  location /.well-known/matrix/ {
    root /var/www/wellknown;
    default_type application/json;
    add_header Access-Control-Allow-Origin *;
  }
}

server {
  listen 443 ssl;
  listen [::]:443 ssl;
  server_name matrix.example.com;
  ssl_certificate     /etc/letsencrypt/live/matrix.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/matrix.example.com/privkey.pem;
  client_max_body_size 100m;

  location ~ ^(/_matrix|/_synapse/client) {
    proxy_pass http://127.0.0.1:8008;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $host;
  }
}

Der Access-Control-Allow-Origin-Header an der Well-known-Position wird von Web-Clients verlangt und von praktisch jedem vergessen. Ohne ihn funktionieren Desktop-Clients, aber Browser-Clients können Ihren Server überhaupt nicht finden.

mkdir -p /var/www/wellknown/.well-known/matrix
systemctl restart matrix-synapse nginx

4. Ein Benutzer

register_new_matrix_user -c /etc/matrix-synapse/homeserver.yaml http://127.0.0.1:8008

Beantworten Sie die Eingabeaufforderungen, machen Sie das erste Konto zum Admin und lassen Sie die offene Registrierung deaktiviert. Ein Homeserver mit offener Registrierung wird innerhalb von Tagen zur Spam-Quelle, und andere Server werden Ihren Datenverkehr ablehnen, lange bevor Sie es bemerken.

Verifizieren

Arbeiten Sie sich nach außen vor. Zuerst: Antwortet die Software überhaupt?

curl -s https://matrix.example.com/_matrix/client/versions | head -c 200
curl -s https://matrix.example.com/_matrix/federation/v1/version

Dann: Wird die Delegation korrekt ausgeliefert, mit Port und richtigem Content-Type?

curl -si https://example.com/.well-known/matrix/server | grep -E "content-type|m.server"
curl -s https://example.com/.well-known/matrix/client

Dann: Löst sich Ihr Signaturschlüssel auf? Andere Server holen diesen ab, bevor sie überhaupt mit Ihnen sprechen:

curl -s https://matrix.example.com/_matrix/key/v2/server | head -c 300

Schließlich der einzige Test, der zählt. Melden Sie sich mit einem Client an, treten Sie einem öffentlichen Raum bei, der auf einem fremden Homeserver gehostet wird, und senden Sie eine Nachricht. Dann lesen Sie den Föderationsstatus über die Admin-API, mit dem Access Token, das Ihr Client in den Einstellungen zeigt:

curl -s -H "Authorization: Bearer <admin token>" \
  "https://matrix.example.com/_synapse/admin/v1/federation/destinations" | head -c 400

Jedes Ziel sollte eine kürzliche erfolgreiche Transaktion und kein Retry-Intervall zeigen. Ziele mit wachsendem retry_interval sind Server, die Sie nicht erreichen können; wenn jedes Ziel so aussieht, liegt das Problem an der Delegation und nicht am Netzwerk, und Schritt drei ist der Ort, an dem Sie suchen sollten.

journalctl -u matrix-synapse --since "10 min ago" | grep -i "federation" | tail -20

Danach

Beim ersten Beitritt zu einem sehr großen Raum wird ein Kern für einige Minuten voll ausgelastet und eine große Menge an Zustand geladen. Das ist normal, passiert einmal pro Raum, und es ist der Hauptgrund, warum Leute Synapse für langsam halten. Für Audio und Video benötigen Sie einen TURN-Server neben diesem; coturn auf derselben Instanz versorgt eine kleine Community, wobei er einen eigenen UDP-Portbereich in der Firewall benötigt. Föderation ist in beide Richtungen gesprächig, was bei der Standortwahl zu bedenken ist: Unser Standortverzeichnis listet die Laufzeiten auf, die wir selbst messen.

Bereit, wenn Sie es sind

Wählen Sie eine Stadt. Wählen Sie eine Größe. Bezahlen Sie in Coins.

Keine Formulare darüber, wer Sie sind, kein Warten auf einen Menschen, der Sie genehmigt, kein Anruf zur Verifizierung. Die Rechnung wird beglichen, und die Zugangsdaten landen in Ihrem Posteingang.