`external-ip` pointait sur 91.121.90.228, l'adresse d'admin.opytex.org, alors que la stack tourne sur chioggia (188.165.240.182) : coturn annonçait aux clients une machine qui n'écoute rien sur ces ports. 3478 n'était par ailleurs publié qu'en TCP, alors qu'un client TURN tente l'UDP en premier. Les deux défauts se cumulaient, le relais était inopérant. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Infrastructure
Description de l'infrastructure, DNS et services : les zones OVH et les rewrites
AdGuard via OpenTofu (dns/), les stacks Docker Compose déployées sur chioggia
(stacks/, une par domaine).
Secrets (SOPS + age)
Les secrets sont chiffrés dans le dépôt. Rien de déchiffré ne doit jamais toucher
le disque : sops exec-env injecte les valeurs en variables d'environnement le temps
d'une commande.
Créer une clé
Une clé par machine. La privée ne quitte jamais sa machine ; seule la publique
est recopiée dans .sops.yaml.
# poste admin — la privée va dans pass, jamais sur le disque
age-keygen | pass insert -m infra/age-key
pass show infra/age-key | age-keygen -y # publique -> .sops.yaml
# serveur (chioggia, ou toute nouvelle machine) — sous le compte qui déploie
# les stacks, PAS root : sops lit ce chemin par défaut, sans aucune variable
# d'environnement à exporter
mkdir -p ~/.config/sops/age
(umask 077; age-keygen -o ~/.config/sops/age/keys.txt)
age-keygen -y ~/.config/sops/age/keys.txt # publique -> .sops.yaml
age-keygen écrit la clé privée sur stdout (trois lignes, dont # public key:)
et un rappel de la publique sur stderr — c'est bien la privée seule qui entre dans
pass. Vérifier avec pass show infra/age-key.
Ajouter ensuite la publique au bon creation_rules de .sops.yaml, puis
rechiffrer l'existant — sans quoi la nouvelle machine ne pourra rien lire :
sops updatekeys -y stacks/*/secrets.env.yaml
Où sont les clés
| Machine | Clé privée | Comment sops la trouve |
|---|---|---|
| Poste admin | dans pass, sous infra/age-key |
export SOPS_AGE_KEY="$(pass show infra/age-key)" |
| chioggia | ~/.config/sops/age/keys.txt (600) du compte de déploiement |
emplacement par défaut : rien à exporter |
Sur chioggia, le compte qui déploie est aussi celui qui déchiffre. Il est membre du
groupe docker et n'a donc jamais besoin de sudo — ni pour git pull, ni pour
docker compose, ni pour lire sa clé.
.sops.yaml définit qui déchiffre quoi : chioggia n'a accès qu'aux
stacks/*/secrets.env.yaml. Les credentials OVH et AdGuard restent gérés par pass
(voir dns/) et sont hors de sa portée — une compromission du serveur ne doit pas
donner le domaine.
Recettes
# éditer un secret (rechiffré à la sortie de l'éditeur)
sops edit stacks/vault.opytex.org/secrets.env.yaml
# créer les secrets d'une nouvelle stack — le chemin n'a pas besoin d'exister,
# rien n'est écrit en clair
sops edit stacks/<nom>/secrets.env.yaml
# lire sans éditer
sops -d stacks/vault.opytex.org/secrets.env.yaml
# déployer, depuis le dossier de la stack sur chioggia
sops exec-env secrets.env.yaml 'docker compose up -d'
# après TOUTE modification de .sops.yaml (nouvelle machine, clé retirée).
# Accepte plusieurs fichiers malgré l'aide qui annonce `file` au singulier.
# Sans -y, sops demande une confirmation par fichier — mais montre le diff
# des destinataires, utile pour vérifier quelle creation_rules s'applique.
sops updatekeys -y stacks/*/secrets.env.yaml
Le format est du YAML plat (CLE: valeur) : exec-env ne sait pas exporter une
structure imbriquée.
Les pièges à connaître
sops updatekeysn'est pas automatique. Modifier.sops.yamlne rechiffre rien ; les fichiers existants restent lisibles par les anciennes clés seulement.- Une clé illisible produit un message trompeur. Mauvais propriétaire ou mauvais
chmodsurkeys.txtdonneRecovery failed because no master key was able to decrypt the file— pas un mot sur les permissions. Vérifierls -lsur la clé avant de suspecter le chiffrement. - Les composes déclarent
VAR: ${VAR:?}. Undocker compose uplancé sanssops exec-envéchoue immédiatement, au lieu de recréer les conteneurs avec des valeurs vides. Ne pas « simplifier » enVAR: ${VAR}. - Perdre les deux copies de la clé age = perdre tous les secrets du dépôt.
Celle du poste vit dans
pass, à sauvegarder hors ligne. Celle de chioggia est dans un répertoire personnel : elle n'est PAS couverte par le backup tant qu'elle n'est pas ajoutée àMANUAL_DIRECTORIESdansbackup.conf.
DNS
Gestion des DNS
Une fois les enregistrements importés, vous pouvez :
- Modifier les enregistrements dans
ovh_dns_records.tf - Ajouter de nouveaux enregistrements
- Appliquer les changements avec
terraform apply
Exemple d'enregistrement
resource "ovh_domain_zone_record" "www" {
zone = "example.com"
subdomain = "www"
fieldtype = "A"
ttl = 3600
target = "203.0.113.1"
}
AdGuard
Gestion automatisée d'AdGuard Home via Terraform, incluant :
- Configuration des règles de réécriture DNS pour le réseau local
- Authentification sécurisée via
pass(gestionnaire de mots de passe)
Prérequis
- Terraform >= 1.0
passconfiguré avec les credentials AdGuard- Accès à l'instance AdGuard Home
Utilisation
cd dns
terraform init
terraform plan
terraform apply
Configuration
Les rewrites DNS sont définis dans dns/variables.tf et peuvent être personnalisés via un fichier .tfvars.