feat(matrix): clean livekit, nginx
This commit is contained in:
@@ -194,6 +194,28 @@ elle.** Aucun des deux ne le signalera : coturn et LiveKit démarrent
|
||||
normalement en annonçant une adresse erronée, et seuls les appels échouent —
|
||||
sans erreur dans les logs, puisque du point de vue des serveurs tout va bien.
|
||||
|
||||
## Le chemin des requêtes clientes
|
||||
|
||||
`matrix.poneyworld.net` passe par Traefik, puis nginx, puis Synapse. Deux
|
||||
conséquences à ne pas défaire :
|
||||
|
||||
- nginx doit propager la chaîne avec `$proxy_add_x_forwarded_for`, jamais
|
||||
`$remote_addr` : ce dernier vaut l'adresse de **Traefik**, et l'utiliser
|
||||
écrase l'en-tête posé en amont. Synapse voit alors tous les clients sous une
|
||||
seule adresse — la limitation de débit à la connexion devient un compteur
|
||||
partagé par tous les comptes, et les journaux d'authentification perdent leur
|
||||
intérêt. Côté Synapse, le listener 8008 doit porter `x_forwarded: true`.
|
||||
- `crowdsec@file` est posé sur les routeurs `matrix_nginx` (API client) et
|
||||
`element` (interface web), **délibérément pas sur `synapse`** : ce dernier
|
||||
sert la fédération, qui arrive de milliers de serveurs distants. Une décision
|
||||
de bannissement à cet endroit couperait les correspondants.
|
||||
|
||||
Contrôle de la chaîne, une seule adresse en `172.x` signalant le problème :
|
||||
|
||||
```sql
|
||||
SELECT ip, count(*) FROM user_ips GROUP BY ip ORDER BY count DESC LIMIT 10;
|
||||
```
|
||||
|
||||
## Versions d'images
|
||||
|
||||
Toutes les images sont épinglées au patch. Les tags d'amont ne suivent pas la
|
||||
|
||||
@@ -7,6 +7,15 @@ services:
|
||||
synapse:
|
||||
image: matrixdotorg/synapse:v1.159.0
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
# Forme longue : `depends_on` court n'ordonne que le DÉMARRAGE, sans
|
||||
# attendre que la base accepte les connexions.
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
env_file:
|
||||
- env_file
|
||||
volumes:
|
||||
@@ -26,6 +35,8 @@ services:
|
||||
db:
|
||||
image: postgres:18.6
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
env_file:
|
||||
- env_file
|
||||
environment:
|
||||
@@ -33,6 +44,12 @@ services:
|
||||
POSTGRES_INITDB_ARGS: --encoding=UTF-8 --lc-collate=C --lc-ctype=C
|
||||
volumes:
|
||||
- matrix_db:/var/lib/postgresql
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
|
||||
interval: 15s
|
||||
timeout: 3s
|
||||
retries: 20
|
||||
start_period: 30s
|
||||
networks:
|
||||
- default
|
||||
labels:
|
||||
@@ -42,12 +59,27 @@ services:
|
||||
redis:
|
||||
image: valkey/valkey:9.1.1
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
healthcheck:
|
||||
test: ["CMD", "valkey-cli", "ping"]
|
||||
interval: 15s
|
||||
timeout: 3s
|
||||
retries: 20
|
||||
networks:
|
||||
- default
|
||||
|
||||
nginx:
|
||||
image: nginx:1.30.4
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
# `proxy_pass http://synapse:8008` est résolu au CHARGEMENT de la config :
|
||||
# sans ce depends_on, nginx s'arrête sur « host not found in upstream » au
|
||||
# démarrage de la machine et ne revient que par la boucle `restart`.
|
||||
depends_on:
|
||||
synapse:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- ./nginx/matrix.conf:/etc/nginx/conf.d/matrix.conf:ro
|
||||
- ./nginx/www:/var/www/:ro
|
||||
@@ -60,11 +92,14 @@ services:
|
||||
- traefik.http.routers.matrix_nginx.entrypoints=web-secure
|
||||
- traefik.http.routers.matrix_nginx.rule=Host(`matrix.poneyworld.net`)
|
||||
- traefik.http.routers.matrix_nginx.tls.certresolver=letsencrypt
|
||||
- traefik.http.routers.matrix_nginx.middlewares=crowdsec@file
|
||||
- traefik.http.services.matrix_nginx.loadbalancer.server.port=80
|
||||
|
||||
web:
|
||||
image: vectorim/element-web:v1.12.26
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
volumes:
|
||||
- ./element/config.json:/app/config.json:ro
|
||||
networks:
|
||||
@@ -76,12 +111,15 @@ services:
|
||||
- traefik.http.routers.element.entrypoints=web-secure
|
||||
- traefik.http.routers.element.rule=Host(`chat.poneyworld.net`)
|
||||
- traefik.http.routers.element.tls.certresolver=letsencrypt
|
||||
- traefik.http.routers.element.middlewares=crowdsec@file
|
||||
- traefik.http.services.element.loadbalancer.server.port=80
|
||||
|
||||
livekit:
|
||||
image: livekit/livekit-server:v1.13.5
|
||||
command: --config /etc/livekit.yaml
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
environment:
|
||||
# `keys:` a été retiré de livekit.yaml : la paire arrive ici, où
|
||||
# l'interpolation ${...} de Compose s'applique.
|
||||
@@ -105,8 +143,14 @@ services:
|
||||
lk-jwt:
|
||||
image: ghcr.io/element-hq/lk-jwt-service:0.6.0
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
depends_on:
|
||||
- livekit
|
||||
environment:
|
||||
LIVEKIT_JWT_BIND: ":8081"
|
||||
# Pas de LIVEKIT_JWT_BIND : le healthcheck de l'image assemble
|
||||
# `http://localhost:` + la valeur, ce qui donne un double deux-points et
|
||||
# le fait échouer. Le défaut (:8080) est le seul réglage qui fonctionne.
|
||||
LIVEKIT_URL: wss://livekit.opytex.org
|
||||
LIVEKIT_KEY: ${LIVEKIT_KEY:?}
|
||||
LIVEKIT_SECRET: ${LIVEKIT_SECRET:?}
|
||||
@@ -120,11 +164,13 @@ services:
|
||||
- traefik.http.routers.lkjwt.entrypoints=web-secure
|
||||
- traefik.http.routers.lkjwt.rule=Host(`livekit.opytex.org`) && (PathPrefix(`/sfu/get`) || PathPrefix(`/get_token`) || PathPrefix(`/healthz`))
|
||||
- traefik.http.routers.lkjwt.tls.certresolver=letsencrypt
|
||||
- traefik.http.services.lkjwt.loadbalancer.server.port=8081
|
||||
- traefik.http.services.lkjwt.loadbalancer.server.port=8080
|
||||
|
||||
coturn:
|
||||
image: coturn/coturn:4.17.2
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
# Les deux secrets ne peuvent pas venir du fichier de conf : coturn n'y
|
||||
# interpole rien et n'offre aucune option `...File`. Voir README.md.
|
||||
command:
|
||||
@@ -134,6 +180,12 @@ services:
|
||||
- --cli-password=${TURN_CLI_PASSWORD:?}
|
||||
volumes:
|
||||
- ./coturn/turnserver.conf:/etc/coturn/turnserver.conf:ro
|
||||
# `verbose` dans turnserver.conf journalise chaque allocation et chaque
|
||||
# permission : sans borne, le fichier json croît sans fin.
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "1m"
|
||||
# 3478 doit être publié en UDP autant qu'en TCP : un client TURN tente
|
||||
# l'UDP en premier. 5349 (TURNS) reste en TCP seul, c'est du TLS.
|
||||
ports:
|
||||
|
||||
@@ -5,7 +5,10 @@ server {
|
||||
# Traefik -> nginx -> synapse
|
||||
location /_matrix {
|
||||
proxy_pass http://synapse:8008;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
# $remote_addr vaut ici l'adresse de Traefik, pas celle du client : l'utiliser
|
||||
# ÉCRASE l'en-tête posé par Traefik et rend tous les clients identiques aux
|
||||
# yeux de Synapse. $proxy_add_x_forwarded_for complète la chaîne existante.
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
client_max_body_size 128m;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user