Le dépôt accueille désormais les stacks Docker de chioggia (serveur dédié) en plus du DNS et d'AdGuard : « Home Infrastructure » n'était plus exact. Renommage du dossier de travail en `infra`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
147 lines
5.2 KiB
Markdown
147 lines
5.2 KiB
Markdown
# 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`.
|
|
|
|
```bash
|
|
# 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 :
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
# é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
|
|
|
|
```hcl
|
|
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
|
|
|
|
```bash
|
|
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`.
|