Set-OPS-Public/docs/catalogue-services.md
Daniel Allaire 3ea0c95492
Some checks are pending
verifier / verifier (push) Waiting to run
sauvegarde : l etat d un locataire quitte enfin sa propre flotte
Chezlepro rangeait ses instantanes sur une VM DE SA PROPRE FLOTTE. Raser
l ecosysteme pour le reconstruire, c etait raser le filet avec.

Le site a son depot ; les neuf detenteurs d etat y deposent ; une
restitution est sortie (annuaire LDAP lisible, hors flotte).

Isolation par compte Unix, pas par convention : home 0700, cle exclusive,
racine partagee a root en 0711 (traversable, non listable). Les deux refus
constates. Le site heberge du chiffre : il ne peut ni lire ni ouvrir, d ou
la verification deplacee chez le locataire qui detient la cle.

Quatre defauts reveles par ce deuxieme usage :
- la racine des depots ne peut etre le home de personne (StrictModes rendait
  Permission denied publickey pour un refus de CHEMIN)
- la racine nie le TLD internal, et harden-below-nxdomain etendait ce non a
  toute la zone sans jamais interroger l autoritatif : aucun locataire ne
  pouvait nommer un service du site
- le gabarit transporte des fichiers de durcissement perimes, et les machines
  du site ne recoivent jamais ssh_hardening
- MaxStartups compte les connexions non authentifiees : un depot de site en
  voit la somme de ses locataires

Constat non corrige : les machines du site ne sont pas durcies.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
2026-09-01 22:16:20 -04:00

17 KiB

Catalogue des services

Pour qui : le mainteneur — ce que le moteur sait déployer, sous quel nom de groupe, et jusqu'où c'est éprouvé.

Ce document nomme les services que le moteur sait déployer, et la règle qui lie un groupe à son playbook :

groupe opérationnel -> playbooks/groupes/<groupe>.yml     (P04 le prouve)

Le rôle porte le nom du groupe : serveur_keycloak, client_pki. Il n'y a pas de nom court séparé. Seule exception, serveur_durci : un groupe dont le playbook compose onze rôles de durcissement (hardening_packages, sysctl_hardening, apparmor, auditd, fail2ban_ssh, ssh_hardening, nftables_baseline…) plutôt qu'un rôle homonyme.

La nomenclature des VM et des VMID est documentée dans docs/nomenclature-vm.md.

Un service central peut partager un hôte avec d'autres services de la même fonction opérationnelle (plusieurs applications par VM). La relation stricte est entre groupe et playbook, pas entre groupe et VM.

Modèle à jour : chaque service est une application (instance/plan/applications.yml). Voir docs/plan-et-generation.md.

État d'implémentation des rôles

Mise à jour (2026-08-18), vérifiée rôle par rôle contre roles/. Les 29 groupes serveur_* / client_* de ce catalogue ont tous leur rôle et leur playbook. Aucune capacité annoncée ici n'est un point d'ancrage vide.

Éprouvés sur VM réelles. Le 2026-08-13, la flotte a été reconstruite depuis zéro — 43 groupes, 0 échec, 37 minutes — puis remontée d'un seul trait. Ce n'est donc plus « du code validé » : chaque rôle a repris une machine nue et l'a menée à l'état voulu.

Ce que la reconstruction couvre, par capacité :

Capacité Rôles Ce qui est éprouvé
Socle et durcissement serveur_debian, serveur_durci clone du gabarit doré → machine conforme
Confiance serveur_step_ca, client_pki mTLS avec SAN dérivés du plan, renouvellement
Noms serveur_powerdns, client_resolveur autoritaire interne + résolveur local
Identité serveur_openldap, serveur_keycloak LDAPS, SSO OIDC, fédération LDAP automatisée (tasks/federation-ldap.yml), exposé par le plan (auth.<domaine>)
Passerelle SSO serveur_oauth2_proxy SSO devant une app sans OIDC natif (éprouvé sur Icinga Web 2)
Données serveur_postgresql, serveur_redis bases et comptes dérivés du registre, TLS verify-full
Courriel serveur_postfix, serveur_dovecot, serveur_rspamd SMTP→LDAP→LMTP→IMAP, antispam, DKIM
Edge serveur_nginx terminaison TLS, publication des expose: du plan
Observabilité serveur_prometheus, serveur_loki, serveur_grafana métriques, journaux, tableaux sous SSO
Supervision serveur_icinga, serveur_icingaweb2 Icinga 2 + IcingaDB + Web 2 + BPM, au SSO
Forge serveur_forgejo Git + PostgreSQL + SSO OIDC
Collaboration serveur_nextcloud, serveur_collabora (natif, plus de conteneur) déployés par la reconstruction, base et client OIDC dérivés du plan — usage (dépôt de fichier, édition partagée) non consigné comme preuve
Plateforme webapp serveur_web_frontal, serveur_web_dorsal sites statiques et webapps natives (venv + systemd + nginx), zéro conteneur
Sauvegardes serveur_backup, client_backup restic hors-nœud, restauration éprouvée (2026-08-12 : la donnée revient)
Exploitation serveur_ops le poste depuis lequel l'ecosysteme se reconstruit : Ansible epingle, genome clone depuis sa propre forge, cle SSH propre — sans la voute ni son mot de passe
Source d'artefacts serveur_artefacts, client_artefacts cache apt de l'ecosysteme (apt-cacher-ng) : les paquets viennent de chez soi, pas de six serveurs etrangers — mode hors ligne pour prouver ce que le cache detient vraiment
Runner de tenant serveur_ops_tenant le pouvoir de configurer : la voute de l'ecosysteme, deposee CHIFFREE sur son propre runner. Sans elle un runner calcule son inventaire et ne peut rien en faire — chaque role qui demande un secret echoue sur son assertion. N'atteint ni la fabric ni la frontiere
Runner de site serveur_ops_site le pouvoir de materialiser : creer et detruire des VM sur la fabric. Detient la voute du SITE, chiffree, et n'entre JAMAIS chez un tenant — reserve a l'ecosysteme de l'hebergeur
Resolution serveur_resolveur, client_resolveur UN resolveur recursif par tenant (Unbound), qui recurse depuis la racine et delegue la zone souveraine a PowerDNS. Remplace les N demons locaux d'avant le 2026-08-24
Cache du site serveur_cache_site designe LE cache que les ecosystemes voisins prennent comme amont : Debian telecharge une fois pour toute la fabric, et le cache ne voit que des requetes agregees. Reserve a l'ecosysteme de l'hebergeur
Forge du genome du site serveur_forge_site designe LA forge dont les ecosystemes de ce site se reproduisent (D-81), et l'ouvre a eux. Marqueur : serveur_forgejo installe.
Resolveur du site serveur_resolveur_site designe LE resolveur que les ecosystemes de ce site interrogent tant qu'ils n'ont pas le leur. Marqueur : serveur_resolveur installe.
Depot de sauvegarde du site serveur_backup_site designe LE depot ou les ecosystemes de ce site posent leur etat tant qu'ils n'ont pas le leur. Marqueur : serveur_backup installe.
Agents de flotte client_metrique, client_journal, client_smtp collecte et relais sur toute la flotte

Rôles retirés (2026-07-04, supersédés ou hors conception) : serveur_sendmail (→ Postfix), client_dns (→ plancher /etc/hosts + client_resolveur), client_ldap (login LDAP au niveau OS, hors design).

Ce que « éprouvé » ne dit pas. La reconstruction prouve que le moteur mène une machine nue à l'état voulu. Elle ne dit rien de la tenue d'un service sous charge, ni de sa mise à jour dans le temps — deux questions distinctes, et non traitées ici.

Services centraux

Le playbook est toujours playbooks/groupes/<groupe>.yml, et le rôle porte le nom du groupe : la table ne répète donc ni l'un ni l'autre.

Service Groupe
Socle Debian serveur_debian
Durcissement (compose onze rôles) serveur_durci
step-ca (AC interne + ACME) serveur_step_ca
PowerDNS (autoritaire interne) serveur_powerdns
OpenLDAP (source de vérité des identités) serveur_openldap
Keycloak (SSO OIDC, fédéré à l'annuaire) serveur_keycloak
oauth2-proxy (SSO devant une app sans OIDC natif) serveur_oauth2_proxy
PostgreSQL serveur_postgresql
Redis serveur_redis
NGINX — edge : TLS, mandataire inverse, WAF serveur_nginx
Postfix (MTA) serveur_postfix
Dovecot (mailstore IMAP/LMTP) serveur_dovecot
rspamd (antispam, DKIM) serveur_rspamd
Prometheus serveur_prometheus
Loki serveur_loki
Grafana serveur_grafana
Icinga 2 + IcingaDB serveur_icinga
Icinga Web 2 (+ module BPM) serveur_icingaweb2
Forgejo serveur_forgejo
Nextcloud serveur_nextcloud
Collabora serveur_collabora
Dépôt de sauvegarde restic serveur_backup

Couche applicative web

La couche applicative web est distincte de l'edge serveur_nginx :

  • serveur_nginx est l'edge : mandataire inverse, terminaison TLS, WAF ; il reçoit le trafic externe et le route.
  • serveur_web_frontal est la couche présentation web (UI, rendu, assets), servie derrière l'edge.
  • serveur_web_dorsal est la couche application web (API, traitement), consommée par les frontaux.

Le « web » de ces deux groupes est implicite par leur position derrière serveur_nginx. Le jour où un service dorsal n'est pas web (worker batch, file, démon), créer un groupe dédié plutôt que d'élargir serveur_web_dorsal.

Couche Groupe Ce que le rôle pose
Présentation web (sites statiques) serveur_web_frontal nginx + contenu tiré d'un dépôt git souverain (Forgejo), en-têtes de sécurité
Application web (webapps dynamiques) serveur_web_dorsal runtime + service systemd + nginx local — venv/paquets, zéro conteneur

Les deux rôles sont codifiés depuis les spikes du 2026-07-05 (site Alliance Boréale pour le frontal ; monregistraire — FastAPI + uvicorn + SQLite — pour le dorsal), et web-frontal-01 / web-dorsal-01 sont actifs dans le plan de référence.

L'exposition ne passe pas par une dépendance de groupe mais par le plan : le champ expose: d'une application fait dériver le vhost de l'edge, les SAN de son certificat et le plancher /etc/hosts. Une seule ligne au plan, aucune recopie.

Lacune nommée : la dépendance causale serveur_web_frontal → serveur_nginx n'est toujours pas déclarée dans docs/dependances-groupes.yml. Le déploiement d'un frontal n'est donc pas refusé quand l'edge est absent — il aboutit à un site que rien ne publie. À déclarer.

Hôtes du plan de référence

Les quatorze hôtes de l'écosystème de référence, tous à l'état actif, tels que les déclare instance/plan/applications.yml. Un modèle plus petit en porte moins : cette table décrit une répartition éprouvée, pas un minimum requis.

Hôte Applications
infra-pki-01 step-ca
infra-dns-01 PowerDNS
infra-edge-01 NGINX (edge)
edge-mta-01 Postfix, rspamd
infra-mail-01 Dovecot
idm-01 OpenLDAP, Keycloak
data-sql-01 PostgreSQL, Redis
obs-01 Prometheus, Loki, Grafana
mon-01 Icinga 2, Icinga Web 2, oauth2-proxy
forge-01 Forgejo
collab-01 Nextcloud, Collabora
backup-01 dépôt restic
web-frontal-01 site statique
web-dorsal-01 webapp native

Le courriel occupe deux hôtes, et ce n'est pas un détail de taille : edge-mta-01 porte ce qui parle à l'extérieur (Postfix, rspamd), infra-mail-01 ce qui détient les boîtes (Dovecot). La coupure suit l'exposition, pas le logiciel.

Intégrations clientes

Intégration Groupe Posée sur
Confiance PKI / ACME client_pki tout hôte (universelle)
Métriques Prometheus client_metrique tout hôte (universelle)
Journaux vers Loki client_journal tout hôte (universelle)
Résolution locale (Unbound) client_resolveur tout hôte (universelle)
Relais SMTP client_smtp déclaré par hôte, dans le plan
Sauvegarde restic client_backup déclaré par hôte — obligatoire pour tout détenteur d'état (P36)

Universelle ne veut pas dire recopiée : une intégration marquée universelle: true dans son meta/ est posée sur chaque hôte par dérivation, avec l'exemption dérivée du service rendu (P26 : un hôte n'est pas client de ce qu'il sert). Aucune ligne à écrire dans le plan.

client_supervision n'existe pas. Ce catalogue l'a longtemps annoncé ; il n'a jamais eu ni rôle ni playbook, et rien ne l'attend. La supervision s'exerce sans agent sur les hôtes : contrôles actifs depuis le cœur (hostalive) et résultats passifs poussés par l'API par celui qui détient la vérité de terrain — ainsi l'état des sauvegardes est-il rapporté par backup-01, seul à pouvoir lire ses dépôts. Le nom est retiré plutôt que réservé : une case vide dans un catalogue se lit comme une promesse.

Ordre de déploiement — le raisonnement

L'ordre exécutable n'est pas ici. Il vit dans docs/couches-deploiement.yml et docs/dependances-groupes.yml, que P08 prouve cohérents (30 groupes classés, aucun cycle, aucune arête en arrière) et que make reconstruire suit. Ce qui suit en est le raisonnement, utile pour comprendre pourquoi cet ordre-là — et pour placer un service nouveau. Les phases sont franchies : les « intégrations à prévoir » ci-dessous sont posées.

L'ordre ci-dessous privilégie les dépendances structurantes avant les applications.

Phase 1 - Fondations transversales

  1. serveur_powerdns

    • Service central : DNS interne autoritaire et/ou résolution interne selon le design retenu.
    • Raison : les autres intégrations auront besoin de noms stables plutôt que d'adresses IP.
  2. serveur_step_ca

    • Service central : autorité de certification interne et ACME.
    • Intégration à prévoir : client_pki.
    • Raison : les autres services auront besoin de certificats fiables avant d'être exposés proprement.
  3. serveur_nginx

    • Service central : reverse proxy, terminaison TLS, publication HTTP(S), WAF.
    • Intégration à prévoir : publication des services HTTP derrière le proxy.
    • Raison : plusieurs services seront consommés par navigateur ou API et doivent passer par un point d'entrée cohérent.
  4. serveur_postfix

    • Service central : MTA (courriel entrant + sortant interne) + relais SMTP.
    • Intégration à prévoir : client_smtp.
    • Raison : les notifications, réinitialisations de mot de passe et alertes doivent fonctionner tôt.

Phase 2 - Données et identité

  1. serveur_postgresql

    • Service central : base de données relationnelle partagée.
    • Intégration à prévoir : bases dédiées par application, comptes applicatifs et sauvegardes.
    • Raison : Keycloak, Grafana, Icinga Web 2, Forgejo et Nextcloud peuvent dépendre de PostgreSQL.
  2. serveur_openldap

    • Service central : annuaire interne (source de vérité des identités).
    • Consommateurs : Keycloak (fédération/SSO), courriel (Postfix/Dovecot), apps.
    • Raison : l'annuaire doit exister avant l'identité fédérée et le courriel.
  3. serveur_keycloak

    • Service central : SSO/OIDC/SAML.
    • Intégration à prévoir : applications web derrière serveur_nginx.
    • Raison : les applications devraient être branchées au SSO dès leur arrivée plutôt qu'après coup.

Phase 3 - Observabilité minimale

  1. serveur_prometheus

    • Service central : métriques.
    • Intégration à prévoir : client_metrique.
    • Raison : les prochains services doivent être mesurables dès leur déploiement.
  2. serveur_loki

    • Service central : journaux centralisés.
    • Intégration à prévoir : client_journal.
    • Raison : les journaux centralisés accélèrent le diagnostic des services suivants.
  3. serveur_grafana

  • Service central : tableaux de bord.
  • Intégration à prévoir : datasources Prometheus et Loki, authentification Keycloak.
  • Raison : Grafana consolide les métriques et journaux après leur mise en place.

Phase 4 - Supervision active

  1. serveur_icinga, puis serveur_icingaweb2
    • Service central : supervision active, interface web et vues métiers (BPM).
    • Intégrations : PostgreSQL, NGINX, et le SSO via serveur_oauth2_proxy — Icinga Web 2 n'a pas d'OIDC natif.
    • Rien à poser sur les hôtes supervisés : contrôles actifs depuis le cœur, résultats passifs poussés par l'API.
    • Raison : ces composants forment une même capacité de supervision et cohabitent sur mon-01.

Phase 5 - Services applicatifs internes

  1. serveur_redis

    • Service central : cache et files internes.
    • Intégration à prévoir : Nextcloud et autres applications qui en ont besoin.
    • Raison : Redis est une dépendance applicative, pas une fondation globale.
  2. serveur_forgejo

    • Service central : forge Git.
    • Intégration à prévoir : PostgreSQL, NGINX, Keycloak, SMTP, sauvegardes.
    • Raison : la forge devient plus utile après SSO, TLS, SMTP et observabilité.
  3. serveur_nextcloud

    • Service central : collaboration fichiers.
    • Intégration à prévoir : PostgreSQL, Redis, NGINX, Keycloak, SMTP, sauvegardes.
    • Raison : Nextcloud dépend de plusieurs fondations et doit arriver après elles.
  4. serveur_collabora

    • Service central : édition documentaire en ligne.
    • Intégration à prévoir : Nextcloud, NGINX, certificats.
    • Raison : Collabora est une extension de Nextcloud et doit venir après lui.

Règles d'intégration

  • Tout service exposé en HTTP(S) doit prévoir son intégration avec serveur_nginx.
  • Tout service avec authentification humaine doit prévoir son intégration avec serveur_keycloak, sauf justification contraire.
  • Tout service générant des alertes ou notifications doit prévoir client_smtp.
  • Toute VM de service rejoint client_pki, client_metrique, client_journal et client_resolveur — par dérivation, sans rien écrire (intégrations universelles, P26). La supervision, elle, ne pose rien sur l'hôte.
  • Tout hôte qui détient de l'état doit porter client_backup (P36 le refuse sinon).
  • Tout service utilisant un certificat interne doit dépendre de client_pki.
  • Tout rôle serveur doit documenter ses ports, secrets, sauvegardes, dépendances et groupes clients associés.

Les groupes clients peuvent être ajoutés aux VM existantes quand le service central correspondant est réellement disponible.

Dépendances causales

Les dépendances exécutables sont déclarées dans docs/dependances-groupes.yml.

Le runbook DNS initial est dans docs/dns-interne.md.

Ce fichier sert à deux usages :

  • bloquer le déploiement d'un groupe tant que ses prérequis actifs ne sont pas présents ;
  • fournir une source exploitable pour les futurs modèles de supervision.

Un hôte peut porter un groupe client à l'état planifié. Le déploiement est refusé tant que le groupe serveur requis n'a pas au moins un hôte actif.