Set-OPS-Public/docs/sdn-evpn.md
Daniel Allaire 5bc3bceac1
Some checks failed
verifier / verifier (push) Has been cancelled
documentation : la tournee des 74 documents, parce qu un balayage ne lit pas
La revision a commence par un balayage par motifs — chemins morts, cibles make
absentes, comptes derives. Il a trouve une trentaine d ecarts et rate presque
tout le reste : un motif ne voit que ce qui s exprime en motif.

make hote-planifier en est l exemple. La cible EXISTE, donc le controle passait
au vert. C est une cible depreciee qui refuse et sort en 2, recommandee par
AGENTS.md, et qui contredit la REGLE D OR du meme fichier trois ecrans plus
haut. Il fallait lire pour la voir.

74 documents lus un par un. 66 corriges, 8 exacts.

CE QUI ETAIT FRANCHEMENT FAUX

AGENTS.md, la source d autorite, annoncait la flotte pas encore executee contre
des VM reelles. Elle a ete rasee et remontee depuis zero trois fois.
ecosysteme-chezlepro.md, le document montre a un client, portait la meme
phrase : il se sous-vendait gravement.

courriel-conception.md s ouvrait sur aucun role n est encore ecrit, au-dessus de
son propre paragraphe 1 qui les nomme. autorisation.md se terminait sur rien n
est construit alors qu il rapporte des mesures datees du role en fonctionnement.
hebergeur-exploitation.md disait rien n est fait d un depot qui existe.
filiation-emancipation.md se contredisait a deux ecrans de distance.

DES MODELES DECRITS D APRES UN MONDE ANTERIEUR

Le resolveur : cinq documents decrivaient un Unbound par VM en opt-in, trois le
donnaient en exemple d integration FACULTATIVE — il est universel depuis le
2026-08-24. L adressage de nomenclature-vm.md : reseau unique, VLAN 11-15, VMID
a cinq chiffres. Le nommage SDN de sdn-evpn.md contre le code : c est le wiki
qui avait raison.

CE QUI CASSE AU PREMIER ESSAI

Le nom du gabarit dore etait faux a quatre endroits, dont la procedure qui le
FABRIQUE et le critere R2 de l epreuve d operateur independant.
preparer-un-site-hebergeur.md avertissait qu une VM faite a la main serait
detruite : raser derive du plan, il ne la detruira jamais — le risque est l
inverse. Un mot de passe d essai en clair dans un depot public.

DEUX PREUVES ETENDUES, ET UNE QUI SE TROMPAIT ELLE-MEME

P57 couvre les groupes : elle a signale aussitot 29 groupes annonces au-dessus d
un tableau qui en cite 40. P29 confronte le tableau de authentification.md aux
declarations reelles : 12 annonces, 21 reels.

Et P57 imposait un chiffre faux — 56 preuves alors que le depot en porte 57, la
conditionnelle vivant hors de tout comptage. Un garde-fou qui fait respecter une
erreur ajoute l assurance a l erreur.

CE QUI RESTE, ET QU AUCUNE PREUVE NE TIENT

Deux comptes trouves a la main. Et une lacune reelle : rien ne garde les
meta/acces.yml — ni qu un service web-sso en porte un, ni que le groupe qu il
nomme existe. P29 tient les positions d authentification, personne ne tient les
habilitations.

make prouver : CONFORME, 56 OK, 0 echec, 1 saute. 0 lien mort.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-06 16:18:23 -04:00

13 KiB
Raw Blame History

SDN EVPN : le routage passe aux hyperviseurs

Pour qui : le mainteneur du réseau overlay.

Décision d'architecture du 2026-08-02. Elle remplace le routage inter-zone sur les commutateurs L3 par des zones EVPN de Proxmox SDN. Complète docs/frontiere-opnsense.md (la bordure, inchangée) et underlay.yml.example (la fabric, très allégée).

Décidé le 2026-08-03 : une zone EVPN par tenant ; le routage et le filtrage entre les VLAN d'un même tenant se font à ce niveau ; le trafic inter-tenant passe obligatoirement par l'OPNsense.

1. Ce que la décision résout

Les commutateurs Binardat ne savent pas lier une ACL à une interface de routage : l'isolation inter-tenant ne pouvait pas vivre sur la fabric. On l'a d'abord assumé — tout sur les nftables d'hôte — en notant ce qu'on perdait : le plan de gestion n'avait plus de protection réseau contre les tenants, une VM émettant vers 10.0.0.x étant routée localement vers le mgmt des commutateurs, celui de Proxmox et l'OOB/IPMI.

Une zone EVPN est un VRF. Le tenant n'a plus de route vers l'underlay — celui-ci n'est pas dans sa table de routage. Son seul chemin vers l'extérieur passe par le nœud de sortie, donc par l'OPNsense, qui filtre. Le plan de gestion redevient protégé par construction, pas par une règle qu'on pourrait oublier.

C'est le VRF qu'on regrettait de ne pas avoir dans le matériel, obtenu en logiciel.

2. La projection du modèle

Vérifiée sur chaque tenant fédéré (ils étaient deux au moment de la décision, ils sont trois), elle ne demande aucun changement de dérivation :

Objet Proxmox SDN Vient de Exemple (Chezlepro, zone Services-infra)
zone (un VRF) zone_de(index) → t<index> t17
VNet vnet_de(index, libellé) → t<index><zone abrégée> t17serv
tag (VNI) vlan_de(index, zone) 1174
subnet sous_reseau_de(index, zone) 10.17.19.0/24
gateway passerelle_de(index, zone) 10.17.19.1

Les six VNets d'un tenant à l'index 17 : t17fron, t17iden, t17donn, t17serv, t17obse, t17appl.

Rectification du 2026-08-03. Ce tableau annonçait chez17-services-infra, qui aurait été refusé à l'application : zones et VNets sont limités à 8 caractères par Proxmox — l'identifiant sert de base aux noms de bridge, veth et tap. Message amont : « zone ID … can't be more length than 8 characters ».

Le nommage a changé une seconde fois, et ce tableau ne l'avait pas suivi. Il annonçait CHEZ17 / chez174, dérivés de devis_reseau.prefixe() — le nom court du dossier du tenant. La forme en vigueur est plus simple et ne dépend que du seed : t<index> pour la zone, t<index><zone abrégée> pour le VNet (scripts/devis_sdn.py : zone_de, vnet_de). Même préfixe t que les IPSets du pare-feu Proxmox, donc un seul vocabulaire d'un bout à l'autre de la fabric ; minuscules, parce que cet identifiant devient une base de nom d'interface.

La contrainte qui avait motivé la première rectification tient toujours : zones et VNets sont limités à 8 caractères par Proxmox — l'identifiant sert de base aux noms de bridge, veth et tap. Message amont : « zone ID … can't be more length than 8 characters ». Avec t<index>, la marge est confortable jusqu'à l'index 255 (t255 = 4, t255serv = 8). P30 refuse tout dépassement, sur les deux objets.

Les zones créées à la main (VRF0011, VRF0017) sont remplacées. Ce nommage ne disait ni de quel tenant il s'agissait, ni rien qu'on puisse relier au plan : il fallait une table de correspondance pour le lire. Le remplacement se fait pendant que les zones sont vides — les supprimer ne débranche rien. Avec des VM attachées, ce serait une migration ; le devis émet donc une §0 qui les retire d'abord.

make devis-sdn émet ces objets, tenant par tenant : la zone, ses six VNets, ses six sous-réseaux, puis pvesh set /cluster/sdn pour pousser. Non destructif, à relire. Vérification la plus forte disponible : la dérivation reproduit à l'identique les deux zones déjà présentes sur le cluster — même nom, même VNI de VRF, même MTU, même contrôleur.

Le seed index reste la source unique. Le .1 ne change pas d'adresse, il change de porteur : du SVI d'un commutateur vers la passerelle anycast du VNet, présente sur chaque hyperviseur — donc plus proche de la VM, et sans point unique de défaillance.

Effet de bord favorable : un VNI est codé sur 24 bits là où un VLAN plafonne à 4094. La limite du nombre de tenants n'est plus l'espace de VLAN mais le second octet IPv4 du supernet : valider_index borne l'index à 0–255, et 0 est à éviter (les réseaux de service du site y vivent). Le plafond reste, sa cause change.

3. Le partage des responsabilités

Trafic Où il est routé Où il est filtré
entre zones d'un même tenant zone EVPN du tenant (VRF, sur les hyperviseurs) au même endroit
entre tenants sort du VRF → nœud de sortie → OPNsense la frontière, et elle seule
vers l'extérieur idem la frontière
de service à service, sur un hôte — deux barrières : pare-feu Proxmox (make devis-proxmox-fw) puis nftables d'hôte (make flux)

Deux conséquences qui méritent d'être dites.

L'inter-tenant ne peut plus être « oublié ». Il ne circule pas latéralement : il doit sortir du VRF, donc traverser la bordure, qui est en block par défaut. Un flux inter-tenant légitime doit donc être déclaré pour exister — et le registre des flux a désormais le mot-clé qui manquait : voisins_site, « les tenants d'à côté » (scripts/resoudre_flux.py, MOTS_PAIR). Ce paragraphe l'annonçait comme un point ouvert jusqu'au 2026-09-06 ; il est fermé.

La défense est en profondeur, sans coût de maintenance. Le filtrage est-ouest est appliqué deux fois : par l'hyperviseur, puis par l'hôte destinataire. Une VM compromise doit franchir les deux. Et comme les deux dérivent du même registre par les mêmes fonctions, elles ne peuvent pas se contredire — la duplication est dans l'application, jamais dans la décision.

Le commutateur ne voit plus rien du trafic tenant. Il transporte du VXLAN qu'il ne lit pas. Y chercher une trace d'un problème applicatif serait perdre son temps : le miroir utile est sur l'hyperviseur.

4. Ce que le devis switch devient

C'est fait, et piloté par underlay.routage_tenants: sdn. Disparaissent : les VLAN tenants, les SVI de zone, les ACL d'isolation, et les VLAN tenants dans les trunks. En EVPN, aucun VLAN de tenant ne circule sur le fil — seulement du VXLAN encapsulé dans de l'IP.

Restent : les VLAN d'underlay, le SVI de management, les trunks qui ne portent plus qu'eux, les routes, le spanning-tree. La fabric redevient ce qu'elle aurait dû être — un transport IP.

underlay.routeur garde son sens, mais son rôle se réduit : il route l'underlay, plus les tenants.

5. Ce que ça change ailleurs

Le nœud de sortie remplace le prochain saut. En EVPN, le trafic quitte le VRF par un ou plusieurs exit nodes désignés. Ce sont eux, et non plus le commutateur, que l'OPNsense voit comme voisins.

C'est appliqué : en mode sdn, le devis frontière n'émet plus le SVI du commutateur comme prochain saut des routes tenants — il émet le marqueur <NOEUD-DE-SORTIE-EVPN> et dit pourquoi. Une route pointée vers le SVI arriverait sur un équipement qui n'a aucun chemin vers le tenant : c'est le genre de configuration qui s'applique sans erreur et ne fonctionne pas.

À noter : underlay.passerelle_sortie garde son sens — c'est l'adresse du pare-feu sur le lien de transit, donc la sortie de l'underlay, indépendante du routage tenant. Ce sont deux choses distinctes qu'il ne faut pas confondre.

L'overlay est plafonné à 1450 (décision du 2026-08-03) parce que le transport réel — le pont vmbr3 des hyperviseurs — est à 1500 : 1450 + 50 de VXLAN y tient exactement. Conséquence à ne pas manquer : sous 1500, tout ce qui traverse la frontière dépend de la découverte de MTU de chemin, qui a besoin de l'ICMP « fragmentation nécessaire ».

Or le registre des flux ne connaissait que TCP et UDP : ce message ne pouvait pas être déclaré, et la bordure en block l'aurait jeté. Symptôme : la connexion s'établit, les petites requêtes passent, les grosses réponses restent suspendues. protocole: icmp est désormais admis — le champ port porte alors le type (frag-needed) — et le socle déclare les deux sens.

Le MTU du transport est un prérequis vérifié, pas un conseil. VXLAN ajoute 50 octets ; make underlay refuse un réseau de transport sous 1550 dès que routage_tenants: sdn. C'est le premier mur, et le plus déroutant : il ne casse pas franchement, il casse partiellement — le ping passe, les transferts échouent.

Ce qui ne change pas : le plan, le registre des flux, les nftables d'hôte, la frontière OPNsense et ses règles dérivées, la voûte, les preuves. La cible d'émission change ; le modèle non.

6. Ce qui reste à éprouver — avant toute génération

Le principe du dépôt s'applique : éprouver l'outil avant d'écrire le rôle. L'EVPN est la partie la plus jeune de Proxmox SDN, et c'est là que vivent les bogues.

Un tenant de labo, une zone EVPN, deux VNet, une VM dans chacun — et vérifier dans l'ordre :

  1. le MTU de bout en bout, avec des paquets pleins et le bit don't fragment ;
  2. le routage entre VNet d'une même zone (c'est ce qui remplace le SVI du commutateur) ;
  3. l'absence de route vers l'underlay depuis le tenant — c'est le gain principal, il se vérifie par une tentative qui doit échouer ;
  4. la sortie par le nœud de sortie, jusqu'à la bordure ;
  5. le comportement à la perte d'un nœud : la passerelle anycast est censée survivre.

Ce n'est qu'après que la question « comment générer cette configuration » se pose.

7. L'état réel du cluster (reconnaissance du 2026-08-03)

Lecture seule par l'API Proxmox. Le plan de contrôle existe, le plan de données non.

Proxmox 8.4.19 — asgard, gandalf, vishnu
Contrôleur EVPN0017, ASN 65000
Zones VRF0011, VRF0017 — un VRF par tenant, VNI = index, MTU 1450
VNets aucun
Nœuds de sortie aucun — un VRF sans sortie n'a aucun chemin vers la frontière

Deux blocages — levés

Cette section décrivait l'état du 2026-08-02. Les deux sont levés ; on la garde parce que le raisonnement explique le plan d'adressage actuel, qui paraîtrait arbitraire sans lui.

Les VTEP étaient adressés dans un tenant. vmbr3 portait 10.27.19.{41,43,47} — le sous-réseau Services-infra de Chezlepro. Le transport du cluster dérivait donc de l'index d'un tenant : un changement d'index le cassait, une migration l'emportait. Et une VM de cette zone partageait son sous-réseau avec les trois VTEP, ce qui perçait l'isolation à l'endroit même que l'EVPN devait fermer.

Le modèle refusait d'ailleurs d'exprimer cet état : déclarer 10.27.19.0/24 comme réseau d'underlay faisait échouer P23, qui interdit tout chevauchement accidentel avec un supernet tenant. La garde a détecté la faute avant qu'on ne la documente.

Aujourd'hui : les VTEP vivent sur underlay-vxlan — 192.168.50.{41,43,47}, VLAN 50, sur une interface étiquetée dédiée (bond3.50). Le transport ne dérive plus d'aucun index. Pourquoi 50 et pas 11 : sous la règle 192.168.<vlan>, le VLAN 11 aurait produit 192.168.11.0/24 — déjà occupé par le contrôle de la grappe. Un plan d'adressage ne doit pas dépendre de l'ordre d'une migration.

Le pont vmbr3 n'était pas VLAN-aware, et l'adresse du VTEP y vivait donc dans le VLAN natif du port. C'est ce qui rendait le déplacement plus qu'un changement d'adresse — d'où l'interface étiquetée dédiée retenue.

8. Ce qui reste à trancher

  • Où vit la configuration SDN. Elle est par cluster, donc propriété de l'hébergeur — comme underlay.yml, et par le même raisonnement.
  • Le contrôleur EVPN : ASN, voisins, et si l'on fait du BGP avec la bordure ou des routes statiques comme aujourd'hui.
  • Le nombre de nœuds de sortie et leur redondance.
  • Le mot-clé d'un flux inter-tenant dans le registre. Tranché : c'est voisins_site (2026-08-24), né du besoin de chaîner les caches d'artefacts. Cf. §3.
  • La migration depuis l'existant : le tenant Chezlepro tourne déjà sur des VLAN. Passer à EVPN est un changement de plan de transport pour des VM en service — la recette de docs/migration-tenant.md s'applique-t-elle, ou faut-il un chemin plus court ?