Set-OPS-Public/docs/decisions-architecture.md
Daniel Allaire fd62b59989 pare-feu Proxmox : le filtrage est-ouest intra-tenant, dérivé (P25)
`make devis-proxmox-fw` : 34 groupes de sécurité, 40 règles, 2 tenants —
depuis les 57 flux intra-tenant que le registre connaissait déjà.

Défense en profondeur, pas remplacement : l'hyperviseur filtre puis l'hôte
destinataire filtre à nouveau. Coût de maintenance nul, les deux barrières
lisent le registre par les MÊMES fonctions — la duplication est dans
l'application, jamais dans la décision.

Un IPSet par rôle porte les membres, les groupes y renvoient : ajouter un
hôte à un rôle met à jour toutes les règles qui l'autorisent, en un endroit.

Garde ajoutée après coup : Proxmox limite un nom de groupe à 18 caractères.
Ma première version tronquait sans vérifier — deux rôles tronqués au même nom
auraient fusionné leurs règles, donnant à une VM les autorisations d'un rôle
qu'elle ne porte pas, silencieusement. Le préfixe porte maintenant l'index
plutôt que l'étiquette, et une garde échoue sur toute collision. Exercée.

Conséquence consignée : tout ce qui entre dans un tenant passant par la
frontière, le contrôleur Ansible aussi — l'OPNsense devient un prérequis de
déploiement, pas une étape parmi d'autres.

Preuves : 25 OK, 0 échec.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 11:43:32 -04:00

9 KiB

Registre des décisions d'architecture

À quoi sert ce document. Les décisions sont écrites là où elles s'appliquent — frontiere-opnsense.md, sdn-evpn.md, migration-tenant.md, underlay.yml.example — et leur histoire vit dans le CHANGELOG. Ce registre ne les répète pas : il dit quelles décisions existent, pourquoi, et où lire le détail. Sans lui, « pourquoi le /29 et pas le /30 ? » demande de relire vingt entrées de journal.

Ce n'est pas la doctrine de conduite (AGENTS.md §Principes), ni le registre des affirmations prouvables (docs/audit/affirmations.md). Une décision peut n'être gardée par aucune preuve : elle reste une décision.

Qui décide. Toutes ces décisions sont celles de l'opérateur du dépôt. Plusieurs ont été prises sur recommandation — l'assistance propose et argumente, elle ne tranche pas. La distinction compte pour la suite : une décision se renverse par celui qui l'a prise, et savoir qu'elle a été choisie plutôt que héritée change ce qu'on s'autorise à en faire.

Les dates de la §5 sont celles de l'historique git, pas du moment de la conversation : ce sont les seules vérifiables.


1. Le réseau

# Décision Pourquoi Détail Garde
D-01 OPNsense est une frontière nord/sud, pas la passerelle des zones le routage inter-zone reste au débit ligne ; la bordure ne voit pas l'est-ouest frontiere-opnsense.md §1
D-02 Le lien de transit vit dans l'underlay, pas dans un tenant la frontière route vers tous les tenants par le même saut : il ne peut dériver d'aucun index frontiere-opnsense.md §6 P23
D-03 Le /29 de transit : frontières en bas (.1,.2), SVI en haut (.6), .3 réservée deux pare-feux cohabitent pendant une transition ; .3 attend une IP virtuelle CARP frontiere-opnsense.md §6 P23
D-04 Un point de routage porte le même dernier octet sur tous ses sous-réseaux on retient une adresse, pas treize frontiere-opnsense.md §4 P23
D-05 Un seul commutateur route ; les autres restent en L2 pur sans MLAG, dupliquer les SVI créerait autant de conflits d'adresses que de zones underlay.yml.example P23
D-06 Les réseaux déclarent leur fabric ; un devis ne parle que de la sienne le stockage jumbo vit sur ses propres commutateurs — un devis est une configuration, pas un inventaire sdn-evpn.md §4 P23
D-07 Pas d'ACL sur cette fabric (acl_inter_tenant: false) le matériel ne sait pas lier une ACL à un SVI ; des règles jamais liées auraient l'air d'isoler frontiere-opnsense.md §1
D-08 Le routage tenant passe au SDN EVPN — une zone par tenant une zone EVPN est un VRF : l'isolation devient structurelle, pas réglementaire sdn-evpn.md P23 (MTU)
D-09 Le filtrage inter-zone d'un tenant se fait au même niveau (EVPN) là où le routage a lieu sdn-evpn.md §3
D-31 Le filtrage est-ouest est appliqué deux fois : hyperviseur puis nftables d'hôte défense en profondeur ; les deux dérivent du même registre par les mêmes fonctions, donc ne peuvent pas diverger sdn-evpn.md §3 P25
D-32 Tout ce qui entre ou sort d'un tenant passe par la frontière un VRF n'a qu'une sortie ; conséquence : la frontière devient un prérequis de déploiement sdn-evpn.md §3
D-10 L'inter-tenant passe obligatoirement par la frontière il sort du VRF, donc traverse une bordure en block par défaut : il ne peut plus être oublié sdn-evpn.md §3
D-11 La sortie générale est déclarée dans le registre des flux block out est un vrai default-deny ; un besoin oublié ne se manifeste pas par un refus clair frontiere-opnsense.md §8 P09
D-29 L'overlay EVPN plafonne à 1450 ; le transport doit donc dépasser 1500 choix d'exploitation ; l'encapsulation VXLAN coûte 50 octets sdn-evpn.md §5 P23 (MTU du transport)
D-30 L'ICMP « fragmentation nécessaire » est déclaré, dans les deux sens à 1450, tout ce qui traverse la frontière dépend de la découverte de MTU de chemin ; une bordure en default-deny la casse en silence roles/serveur_debian/meta/flux.yml P09
D-12 Nommage : bifrost aux frontières, sleipnir à la fabric Bifröst est le pont vers l'extérieur ; Sleipnir traverse les mondes sans en sortir frontiere-opnsense.md §6

2. Qui possède quoi

# Décision Pourquoi Détail Garde
D-13 Un hébergeur sert plusieurs tenants et a son tenant par défaut Chezlepro est les deux à la fois, ce qui masquait la distinction frontiere-opnsense.md §2
D-14 underlay.yml appartient à l'hébergeur, monté par symlink ce sont ses commutateurs, ses câbles ; le moteur est générique, un tenant n'en possède pas sdn-evpn.md, underlay.yml.example
D-15 Ce symlink ne suit pas make instance-utiliser basculer le tenant actif ne change pas la fabric frontiere-opnsense.md §2
D-16 Les intrants de la frontière se lisent chez l'hébergeur un hébergeur n'a qu'une frontière pour tous ses tenants frontiere-opnsense.md §2
D-17 L'hébergeur n'est pas déclaré : le symlink le désigne une seconde déclaration ouvrirait deux valeurs contradictoires frontiere-opnsense.md §2
D-18 Chaque tenant a un responsable désigné sans lui, « qui peut décider de déménager cette organisation ? » se pose au pire moment migration-tenant.md §3

3. Les secrets

# Décision Pourquoi Détail Garde
D-19 Une seule voûte par instance (group_vars/all/vault.yml) un mot de passe, un endroit config-proxmox.md P18
D-20 La liste des secrets se recense, elle ne s'écrit pas trois copies manuelles ont existé, toutes ont divergé intrants-communs.md §H P18
D-21 L'empreinte du root CA n'est pas un secret : elle se dérive à chaud un from-zero régénère l'AC ; figée en voûte, elle serait périmée roles/client_pki/README.md
D-22 Migrer un tenant, c'est révoquer, pas transmettre sinon l'ancien hébergeur garde à vie l'accès aux secrets d'un client parti migration-tenant.md §6

4. La méthode

# Décision Pourquoi Détail Garde
D-23 Les cibles hors flotte reçoivent un devis, pas un rôle commutateurs, frontière et SDN sont des objets de cluster ; un rôle boucle sur des hôtes sdn-evpn.md §7
D-24 Un devis n'écrit rien : il se relit, puis s'applique proportionné au risque — une config ratée partitionne tout un cluster frontiere-opnsense.md §7
D-25 Le dépôt n'affirme pas que ses devis s'appliquent, il affirme qu'ils dérivent leur syntaxe dépend d'un matériel que le dépôt ne possède pas audit/affirmations.md §10
D-26 Un modèle peut porter un underlay ; tous les hébergeurs n'ont pas le même matériel générique public, étoffés en privé exemples/modeles/socle/README.md P17
D-27 Migration : le receveur est prouvé prêt avant tout gel l'interruption se réduit au delta et à la propagation DNS migration-tenant.md §4
D-28 Le mandat de migration est signé par le tenant, pas convenu entre hébergeurs il n'y a pas de registre central pour arbitrer ; une organisation n'est pas la propriété de son hébergeur migration-tenant.md §2

5. Décisions renversées

Les garder évite de refaire le chemin, et explique pourquoi le code porte encore des branches qui semblent inutiles.

Décision Tenue du … au … Renversée par Pourquoi Ce qu'il en reste
L'isolation inter-tenant est portée par des ACL de commutateur 2026-07-07 → 08-03 059d76a le matériel ne sait pas lier une ACL à une interface de routage acl_inter_tenant: true reste le défaut : une autre fabric peut en être capable
Le routage inter-zone est porté par les commutateurs L3 2026-07-07 → 08-03 e5ce2b9 sans ACL, l'isolation devenait déclarative ; EVPN la rend structurelle routage_tenants: switch reste le défaut et reste généré
L'underlay.yml vit à la racine du moteur, gitignoré 2026-07-24 → 08-02 0eae97c consommé par deux générateurs, validé par une preuve, versionné nulle part SETOPS_UNDERLAY permet toujours de le pointer ailleurs

Ce que ces renversements ont en commun. Aucun ne vient d'un changement d'avis : les trois viennent d'un fait découvert après la décision — une commande absente de l'aide du matériel, une capacité manquante, une dizaine de modifications irrécupérables. C'est l'argument le plus fort pour éprouver avant de figer.