Douze constructions

Un serveur Matrix dont la fédération fonctionne réellement

Synapse sur une petite instance Ryzen avec Postgres, délégation via des fichiers well-known plutôt que des enregistrements SRV, et vérification qui atteint d'autres serveurs.

Ce que cela construit

Un serveur domestique à example.com, fonctionnant sur matrix.example.com, fédérant correctement avec tout le monde. Postgres en dessous, nginx devant, la délégation gérée par deux petits fichiers JSON, et l'inscription fermée pour que votre serveur ne devienne pas le relais gratuit de quelqu'un en une semaine.

La fédération est l'endroit où ces installations échouent généralement, et presque jamais à cause de Synapse. Le serveur fonctionne, les messages locaux fonctionnent, puis rien ne vient de l'extérieur. En pratique, la cause est presque toujours la délégation : l'identité du serveur et l'adresse où il vit sont deux choses différentes, et le mécanisme qui les relie est facile à mal configurer subtilement.

Avant de commencer

  • Un R-4 suffit pour quelques dizaines d'utilisateurs. Synapse est plus gourmand en mémoire qu'en CPU, et rejoindre de grandes salles fédérées est la seule chose qui le fera transpirer.
  • Deux noms dans le DNS : example.com, qui est l'identité de votre serveur et apparaît dans chaque identifiant d'utilisateur, et matrix.example.com, qui est l'endroit où le logiciel écoute réellement.
  • Des certificats pour les deux. Le premier n'a besoin que de servir deux fichiers statiques.

1. Base de données, avec le bon collationnement

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;"

Le collationnement n'est pas un détail. Synapse refuse de démarrer sur une base créée avec un collationnement autre que C, et l'erreur qu'il affiche lorsque vous vous trompez arrive après avoir déjà importé des données. Faites-le maintenant, correctement, une fois pour toutes.

2. Configuration du serveur domestique

Le paquet Debian demande le nom du serveur lors de l'installation ; répondez example.com, pas le nom d'hôte de la machine. Cette réponse fait partie de chaque identifiant d'utilisateur et de chaque identifiant de salle sur le serveur et ne peut pas être modifiée par la suite sans abandonner le serveur.

Ensuite, modifiez /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

Deux de ces paramètres vous feront économiser du disque et du chagrin. La rétention des médias distants supprime les copies mises en cache des fichiers des autres serveurs après un mois, et sans elle, votre magasin de médias croît indéfiniment avec du contenu que vous n'avez jamais demandé. Les aperçus d'URL sont désactivés parce qu'ils font que votre serveur récupère des adresses arbitraires au nom de toute personne pouvant poster un lien, ce qui est un moteur de falsification de requêtes avec une interface de chat attachée.

x_forwarded: true compte aussi : sans lui, Synapse limite le débit de chaque utilisateur du monde comme s'il s'agissait d'un seul client, car chaque requête semble provenir de nginx.

3. Délégation

Votre identité est example.com et votre serveur est à matrix.example.com. Deux fichiers comblent l'écart. Servez-les à partir de example.com, en HTTPS, avec le bon type de contenu.

/.well-known/matrix/server :

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

/.well-known/matrix/client :

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

Le port dans le premier fichier est obligatoire. Si vous l'omettez, les autres serveurs retombent sur le port 8448, ne trouvent rien qui écoute, et abandonnent silencieusement ; vos utilisateurs signalent alors que la fédération est cassée alors que tous les journaux de votre machine semblent parfaitement sains.

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;
  }
}

L'en-tête Access-Control-Allow-Origin sur l'emplacement well-known est requis par les clients web et oublié par presque tout le monde. Sans lui, les clients de bureau fonctionnent et les clients navigateur ne peuvent pas trouver votre serveur du tout.

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

4. Un utilisateur

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

Répondez aux invites, faites du premier compte un administrateur, et laissez l'inscription ouverte désactivée. Un serveur domestique avec inscription ouverte est une source de spam en quelques jours, et les autres serveurs commenceront à refuser votre trafic bien avant que vous ne le remarquiez.

Vérifiez-le

Travaillez de l'intérieur vers l'extérieur. D'abord, le logiciel répond-il au moins :

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

Ensuite, la délégation est-elle correctement servie, avec le port présent et le type de contenu correct :

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

Ensuite, votre clé de signature se résout-elle. Les autres serveurs la récupèrent avant de vouloir vous parler du tout :

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

Enfin, le seul test qui compte. Connectez-vous avec un client, rejoignez une salle publique hébergée sur un serveur domestique qui n'est pas le vôtre, et envoyez un message. Ensuite, lisez l'état de la fédération à partir de l'API d'administration, en utilisant le jeton d'accès que votre client affiche dans ses paramètres :

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

Chaque destination doit montrer une transaction récente réussie et aucun intervalle de nouvelle tentative. Les destinations avec un retry_interval croissant sont des serveurs que vous ne pouvez pas atteindre ; si chaque destination ressemble à cela, le problème est la délégation plutôt que le réseau, et c'est à l'étape trois qu'il faut regarder.

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

Ensuite

Rejoindre une très grande salle la première fois épinglera un cœur pendant plusieurs minutes et tirera beaucoup d'état. C'est normal, cela arrive une fois par salle, et c'est la principale raison pour laquelle les gens concluent que Synapse est lent. La voix et la vidéo nécessitent un serveur TURN à côté de celui-ci ; coturn sur la même instance gère une petite communauté, bien qu'il veuille sa propre plage de ports UDP dans le pare-feu. La fédération est bavarde dans les deux sens, ce qui vaut la peine de se souvenir lors du choix du site : notre index des emplacements répertorie les temps de round-trip que nous mesurons nous-mêmes.

Prêt quand vous l'êtes

Choisissez une ville. Choisissez une taille. Payez en crypto.

Aucun formulaire sur votre identité, pas d'attente d'approbation humaine, pas d'appel téléphonique pour vérifier quoi que ce soit. La facture est réglée et les identifiants arrivent dans votre boîte mail.