This repository has been archived on 2026-08-21. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Bertrand Benjamin d619f165f0 feat(secrets): chiffrement des secrets avec SOPS + age
Met en place la mécanique de gestion des secrets du dépôt :

- .sops.yaml : deux périmètres séparés par acteur. Les
  stacks/*/secrets.env.yaml sont déchiffrables par le compte de
  déploiement de chioggia ET l'admin ; tout le reste par l'admin seul.
  Une compromission du serveur ne donne donc pas accès aux credentials
  OVH, qui restent gérés par pass.
- .gitignore : tout .env est traité comme un accident. La configuration
  non sensible de chaque stack vit dans un fichier `env_file` versionné.
- README : création des clés, emplacements, recettes et pièges.

Les secrets sont injectés à la volée par `sops exec-env` : aucun fichier
déchiffré ne touche le disque.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 16:38:34 +02:00
2026-08-12 14:46:57 +02:00

Home Infrastructure

Configuration Terraform pour gérer l'infrastructure domestique.

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 updatekeys n'est pas automatique. Modifier .sops.yaml ne 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 chmod sur keys.txt donne Recovery failed because no master key was able to decrypt the file — pas un mot sur les permissions. Vérifier ls -l sur la clé avant de suspecter le chiffrement.
  • Les composes déclarent VAR: ${VAR:?}. Un docker compose up lancé sans sops exec-env échoue immédiatement, au lieu de recréer les conteneurs avec des valeurs vides. Ne pas « simplifier » en VAR: ${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_DIRECTORIES dans backup.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
  • pass configuré 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.

Description
No description provided
Readme 201 KiB
Languages
HCL 100%