Reconstruction complète prouvée (14 VM + sauvegardes + AC supprimées, puis
`make myDay` rebâtit tout ; `make valider` entièrement vert). Bugs corrigés :
- client_pki : empreinte du root CA dérivée dynamiquement de l'autorité
(au lieu d'une valeur figée en Vault) — une AC régénérée a une empreinte neuve.
- serveur_keycloak : assignation de rôle tolérante aux utilisateurs absents
(annuaire vide sur un from-zero).
- serveur_prometheus : ne scrute que les hôtes ACTIFS (client_metrique ∩ hotes_actifs).
- nftables résolu : compatible Docker — remplace la seule table setops_flux (pas de
flush ruleset, préserve les tables Docker) + forward autorise docker0/established.
Sans ça, forward policy drop coupait Collabora (conteneur).
Ajoute playbooks/proxmox/supprimer_vm_debian.yml (suppression par VMID, garde-fous).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ajoute au make valider la preuve de RÉSILIENCE : pour chaque nœud client_backup,
restic restaure le dernier snapshot dans un dossier temporaire (lecture seule sur
le dépôt) et vérifie que des fichiers en sortent.
Éprouvé sur la flotte : 6 dépôts restaurables. La recette a débusqué un vrai trou
(collab-01/Nextcloud sans backup jobs -> service en échec, stockage fichier non
protégé) — corrigé côté instance.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ajoute au make valider la preuve fonctionnelle du service courriel souverain :
envoi via le MTA (sendmail -> postfix -> LDAP -> LMTP) puis vérification de la
remise dans le Maildir avec doveadm (compte testmail), message de test nettoyé.
Éprouvé sur la flotte vivante, sous pare-feu actif : remise confirmée.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Vérifie que les services FONCTIONNENT, pas juste qu'ils sont déployés — complète
les *-verifier (statiques, sur le plan) par une recette fonctionnelle vivante.
playbooks/valider.yml (lecture seule) :
- Prometheus : toutes les cibles de supervision UP (API /targets)
- Edge : les vhosts HTTPS exposés répondent (server_name réels filtrés sur
domaine_interne, statut sain 200/301/302/401/403)
Éprouvé sur la flotte : 7 cibles UP, 8 vhosts OK (sous pare-feu actif).
À venir : courriel bout-en-bout (envoi->IMAP), restauration de sauvegarde.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Aligne sur la convention serveur_* de tous les rôles de service (vars incluses).
Le modèle presence-web (pré-existant) utilisait déjà ces noms -> il colle enfin.
Aussi : serveur_web_dorsal ne chown plus le code (reste root, lecture seule pour
l'app = plus sûr + git idempotent, fini le 'propriété douteuse' au pull).
Idempotence prouvée (2e passage changed=0). lint production.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Runtime (venv/paquets) + service systemd + nginx local, derrière l'edge, ZÉRO
conteneur. Chaque app : git clone (depth 1) → venv + pip → unité systemd durcie
(app en localhost, user webapp, NoNewPrivileges/PrivateTmp) → vhost nginx local
qui la fronte. data_dir persistant pour l'état local (SQLite) ; BD réseau via
resoudre_base sinon.
Éprouvé bout-en-bout sur web-frontal-01 par le rôle : monregistraire (FastAPI+
uvicorn+SQLite) cloné de Forgejo, servi via l'edge en HTTPS step-ca, API OK.
Avec web_frontal, la plateforme webapp native est complète. lint production: 0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
nginx + sites statiques depuis un dépôt git souverain, derrière l'edge. Pas de
conteneur, pas de runtime, pas de BD — l'éthos libre/natif. Chaque site :
git clone → vhost (headers sécurité + CSP self-only, gzip, try_files). SAN edge
+ plancher auto-dérivés. meta/flux.yml (ingress 80 depuis edge).
Spike prouvé sur web-frontal-01 (site Alliance Boréale servi via edge, HTTPS
step-ca vérifié, CSP en place). NB : le chemin git-clone est codifié mais le
spike a servi via copie locale → à éprouver (pousser le site en Forgejo).
Les apps dynamiques (dorsal systemd) = rôle à venir. ansible-lint production: 0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Conteneur collabora/code (restart always), publié sur localhost + IP LAN
(gotcha : bind localhost seul → 502 depuis l'edge), aliasgroup = domaine
Nextcloud, ssl.termination à l'edge, attente santé /hosting/capabilities.
meta/flux.yml (ingress 9980 depuis edge) alimente le registre des flux.
Docker (prouvé au spike) ; CODE natif = option future à spiker. Tag à épingler.
ansible-lint profil production : 0 échec.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Choix : sauvegarder la donnée d'état (non régénérable), pas les VM
(reconstructibles par le code). restic (chiffré, dédupliqué, rétention).
serveur_backup = cible SFTP (backup-01). client_backup = intégration par
nœud : restic + jobs déclaratifs + timer systemd + rétention, secrets voûte.
Prouvé de bout en bout sur le Tier 0 : infra-pki-01 → /etc/step-ca sauvegardé
hors-nœud vers backup-01, restauration byte-identique des clés CA.
Reste : jobs Tier 1 (pg_dump/slapcat/vmail/forgejo) + offsite (3-2-1).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Supprimés : roles/{applications,backup,database,identity,monitoring,
proxmox,storage,web}/ (README seuls, taxonomie abandonnée — l'archi est
plate serveur_*/client_*) et les playbooks-échafaudages debug sans rôle
(nextcloud, collabora, client_supervision, web_frontal, web_dorsal).
Aucun host n'utilise ces groupes ; l'intention des capacités futures
reste documentée dans docs/catalogue-services.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
oauth2-proxy (v7.15.3) place Keycloak devant toute app sans OIDC natif
(auth external, utilisateur via en-tête). Rôle paramétrable, réutilisable.
Éprouvé devant icingaweb2 (backend=external, X-Forwarded-Preferred-Username).
Prouvé : testmail → oauth2-proxy → Keycloak → icingaweb2 /dashboard,
connecté. Ferme le gap LDAP-direct d'icingaweb2.
Réglages appris : insecure_oidc_allow_unverified_email (IdP interne) ;
reverse-proxy passe X-Forwarded-* pas X-Auth-Request-* ; handler nginx en
restart (pas reload) — un changement d'adresse d'écoute n'est pas pris par
un reload gracieux.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
App PHP (php8.4-fpm) + nginx local, exposée par l'edge (auto-dérivé).
Config par fichiers .ini (config/resources/authentication/roles + module
icingadb), pas d'assistant. Base IcingaDB via resoudre_base. Auth LDAP
direct (client_pki sur sup-01) — pas d'OIDC natif (SSO-proxy = raffinement).
Prouvé : testmail (LDAP) se connecte (/dashboard), module IcingaDB affiche
la supervision (hôte icinga). Déploiement failed=0 (frictions dans le
simulateur curl, pas le rôle). Reste : module BPM.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Unbound par nœud (127.0.0.1) : stub-zone vers PowerDNS (interne) + récursion
Internet (ou forward). Alternative dynamique au plancher /etc/hosts. Bascule
resolv.conf protégée (apply+confirm) ET validée avant (Unbound doit résoudre
interne + Internet, sinon pas de bascule → nœud jamais coupé). Sûr par défaut
(apply=false).
Prouvé sur data-sql-01 : dig @127.0.0.1 keycloak/id-sso-01 → PowerDNS,
deb.debian.org → récursion, apt OK. Rollout flotte = opt-in par nœud.
Note : OPNsense embarque Unbound → l'Unbound réseau pourra vivre sur
l'appliance de bordure (nœud public, Étape B) ; ce rôle reste complémentaire.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Réception :25, validation des boîtes par carte LDAP (attribut mail),
remise LMTP réseau vers le mail-store Dovecot (virtual_transport lmtp),
TLS via step_ca (pont de cert), aucune boîte locale. main.cf +
ldap-mailboxes.cf, validé par postfix check. Bind LDAP: vault_openldap_admin.
Validé statiquement (ansible-lint, syntax, rendu main.cf) ; déploiement à suivre.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rôle mail : IMAP :993/:143 + LMTP, auth/annuaire LDAP (serveur_openldap),
stockage Maildir (user vmail), TLS via step_ca (pont de cert + resync au
renouvellement), auth système par défaut neutralisée. Config drop-in en
syntaxe Dovecot 2.4 (mail_driver, ssl_server_cert_file, passdb ldap),
validée par doveconf au déploiement. Sockets Postfix conditionnels à la
présence de l'utilisateur postfix (co-localisation).
Déployé et prouvé sur infra-mail-01 : doveadm auth test — bon mot de passe
accepté, mauvais refusé, cert IMAPS émis par step_ca. Format 2.4 validé
empiriquement avant l'écriture (leçon « éprouver l'outil »).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Stalwart trop jeune/volatil pour un pilier mail critique (config cassée
0.15→0.16, `config apply` annoncé non livré, API REST supprimée pour
JMAP, gros backlog). Pivot vers la stack mature Postfix/Dovecot/rspamd,
100 % configurable par fichiers (alignée au modèle déclaratif Set-OPS).
- Rôle serveur_stalwart retiré (Phase 1 prototypée ; git en garde la trace).
- docs/courriel-conception.md mis à jour ; vault_stalwart_admin retiré.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Stalwart Mail Server v0.16.11, binaire unique natif. Mécaniques réelles
validées empiriquement sur le binaire :
- config.json = objet typé {"@type":"RocksDb","path":…} (DataStore seul) ;
- démarrage IaC en mode récupération (STALWART_RECOVERY_MODE +
STALWART_RECOVERY_ADMIN), admin depuis la voûte (vault_stalwart_admin).
Rôle : install version-épinglée, user système, unité systemd durcie
(CAP_NET_BIND_SERVICE, ProtectSystem), EnvironmentFile pour le secret.
Phase 2 (écouteurs/TLS step_ca/annuaire LDAP/DKIM via API d'admin) à venir.
Validé statiquement (ansible-lint, syntax, rendu config.json).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- clonage/Makefile : chemin proxmox codé en dur `inventories/lab` →
détection lab>principal>production (débloque les instances principal)
- resize disque grow-only : tolère le cas disque dérivé < template
(shrinking not supported), la VM garde le disque du template
- PowerDNS : ne plus redéclarer launch+=bind (déjà posé par le paquet
pdns-backend-bind) → « multiple backends 'bind' » résolu
Trouvés en déployant réellement infra-dns-01 (clone + socle durci +
PowerDNS qui résout) sur le cluster Proxmox.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Nouveau rôle de socle hosts_statiques (dans serveur_debian) : génère
/etc/hosts sur chaque VM depuis l'inventaire. L'écosystème se résout par
nom même DNS éteint, et le bootstrap ne dépend plus du DNS. client_dns
rendu tolérant (inerte sans DNS interne) ; dépendance client_dns→powerdns
passée molle. PowerDNS devient une commodité (zone/externe).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Les cœurs/RAM/disque d'une VM sont estimés depuis l'empreinte des rôles
hébergés (roles/<rôle>/meta/empreinte.yml) sommée au socle SE, au lieu
d'hériter des specs du golden template. Le générateur écrit
proxmox_coeurs/memoire/disque_taille ; le clonage les passe à Proxmox
(omit si absent → aucune régression). Override par hôte dans le plan.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>