flux : l'ICMP entre au registre — l'overlay à 1450 l'exige

Décision : l'overlay EVPN plafonne à 1450. Conséquence invisible : sous 1500,
tout ce qui traverse la frontière dépend de la découverte de MTU de chemin,
donc de l'ICMP « fragmentation nécessaire ».

Or le registre ne connaissait que TCP et UDP. Ce message ne pouvait pas être
déclaré et la bordure en `block in log all` l'aurait jeté : la connexion
s'établit, les petites requêtes passent, les grosses réponses restent
suspendues — la panne la plus coûteuse à diagnostiquer, et celle qu'on impute
d'abord à l'application.

`protocole: icmp` est admis ; le champ `port` y porte le type
(`frag-needed`). Le socle déclare les deux sens. Vérifié : nftables d'hôte
inchangés, le pair `externe` reste sauté.

Reconnaissance (lecture seule) : l'EVPN est à moitié construit — contrôleur
EVPN0017 (ASN 65000), zones VRF0011 et VRF0017, un VRF par tenant avec le VNI
égal à l'index. Aucun VNet, aucun nœud de sortie.

Signalé et non corrigé : les pairs BGP sont dans 10.27.19.0/24, le
sous-réseau Services-infra de Chezlepro. Le transport du cluster dérive de
l'index d'un tenant, et une VM de cette zone partage son sous-réseau avec les
VTEP — l'isolation est percée à l'endroit que l'EVPN devait fermer.

Preuves : 24 OK, 0 échec.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Daniel Allaire 2026-08-03 10:07:30 -04:00
parent 67fc7012b4
commit 70fe6de557
6 changed files with 65 additions and 4 deletions

View file

@ -1,5 +1,34 @@
# CHANGELOG — Set-OPS
## 2026-08-03 (suite 5) — l'ICMP entre au registre, parce que l'overlay descend à 1450
Décision : l'**overlay EVPN plafonne à 1450**. Elle a une conséquence qui ne se voit pas —
sous 1500, tout ce qui traverse la frontière dépend de la **découverte de MTU de chemin**, donc
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 in log all` l'aurait jeté. Symptôme : la connexion s'établit,
les petites requêtes passent, **les grosses réponses restent suspendues** — la panne la plus
coûteuse à diagnostiquer, et celle qu'on impute d'abord à l'application.
`protocole: icmp` est admis ; pour lui, le champ `port` porte le **type** (`frag-needed`). Le
socle déclare les **deux sens** : entrant pour qu'un distant puisse nous demander de réduire
nos paquets, sortant pour que nos hôtes signalent l'overlay aux correspondants.
Vérifié : les nftables d'hôte sont **inchangés** — le pair `externe` reste sauté, ces flux
relèvent de la bordure. Le devis frontière passe à 26 règles.
### Reconnaissance de l'existant (lecture seule)
L'EVPN est déjà **à moitié construit** sur le cluster : Proxmox 8.4.19, contrôleur `EVPN0017`
(ASN 65000), zones `VRF0011` et `VRF0017` — un VRF par tenant, VNI égal à l'index, conforme à
D-08. Mais **aucun VNet** et **aucun nœud de sortie** : le plan de contrôle existe, le plan de
données non.
Signalé, non corrigé : les **pairs BGP sont `10.27.19.41/.43/.47`**, dans le sous-réseau
*Services-infra de Chezlepro*. Le transport du cluster dérive donc de l'index d'un tenant — et
une VM de cette zone partage son sous-réseau avec les trois VTEP, ce qui perce l'isolation à
l'endroit même que l'EVPN devait fermer.
## 2026-08-03 (suite 4) — un index des décisions d'architecture
`docs/decisions-architecture.md`. Les décisions étaient écrites là où elles s'appliquent, et

View file

@ -21,7 +21,7 @@
| P06 | Validateurs de registres (serveurs/apps/bases/domaines) | AFF-003 | ✅ OK | Registre des domaines valide. |
| P07 | GUI (node --check) | AFF-033 | ✅ OK | JS du GUI : syntaxe valide (node --check). |
| P08 | Orchestration (couches + graphe) | AFF-070 | ✅ OK | Orchestration coherente : 30 groupes classes, aucun cycle, aucune arete en arriere. |
| P09 | Flux reseau (schema + matrice) | AFF-071 | ✅ OK | Flux coherents : 29 rôles, 68 flux, schéma + matrice OK. |
| P09 | Flux reseau (schema + matrice) | AFF-071 | ✅ OK | Flux coherents : 29 rôles, 70 flux, schéma + matrice OK. |
| P10 | Handlers <-> notify | AFF-034, AFF-035 | ✅ OK | Tout notify pointe vers un handler du meme role (49 roles). |
| P11 | Syntaxe des playbooks (--syntax-check) | AFF-083 | ✅ OK | playbook: playbooks/proxmox/cloner_vm_debian.yml |
| P12 | Existence des runbooks cites | AFF-010, AFF-011, AFF-012, AFF-083 | ✅ OK | 17/17 runbooks/registres cites presents. |
@ -36,7 +36,7 @@
| P21 | Federation : aucun index en collision | AFF-102 | ✅ OK | Federation coherente : 2 instance(s) federee(s), aucun index en collision. |
| P22 | Plan de recette a jour (genere du wiki) | AFF-002 | ✅ OK | Plan de recette à jour (19 sections). |
| P23 | Underlay sans collision avec la plage tenant | AFF-103 | ✅ OK | Underlay conforme : 5 reseau(x), aucune collision avec la plage tenant. |
| P24 | Frontiere nord/sud : acces d'administration declare | AFF-104 | ✅ OK | CONFORME : frontiere nord/sud, 22 regles, 2 routes, admin=192.168.254.2/32,192.168.255.0/24,192.168.255.2/32. |
| P24 | Frontiere nord/sud : acces d'administration declare | AFF-104 | ✅ OK | CONFORME : frontiere nord/sud, 26 regles, 2 routes, admin=192.168.254.2/32,192.168.255.0/24,192.168.255.2/32. |
## Couverture des affirmations ✅ du registre

View file

@ -35,6 +35,8 @@ sont les seules vérifiables.
| **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-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

View file

@ -91,7 +91,17 @@ le tenant : c'est le genre de configuration qui s'applique sans erreur et ne fon
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.
**Le MTU est un prérequis vérifié, pas un conseil.** VXLAN ajoute 50 octets ; `make underlay`
**L'overlay est plafonné à 1450** (décision du 2026-08-03), donc le transport doit dépasser
1500. 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.

View file

@ -25,6 +25,23 @@ flux:
pair: externe
chiffrement: clair
raison: "Dépôts apt en clair et redirections HTTP des miroirs (l'intégrité vient de la signature des paquets, pas du transport)."
# --- Decouverte de MTU de chemin (PMTUD) ---
# L'overlay EVPN plafonne a 1450 : tout ce qui traverse la frontiere depend de ces
# deux messages. Bloques, la connexion s'etablit, les petites requetes passent et les
# grosses reponses restent suspendues — la panne la plus couteuse a diagnostiquer.
- sens: ingress
port: frag-needed
protocole: icmp
pair: externe
chiffrement: n-a
raison: "ICMP « fragmentation nécessaire » entrant : sans lui, un distant ne peut pas nous demander de réduire nos paquets — les transferts se figent."
- sens: egress
port: frag-needed
protocole: icmp
pair: externe
chiffrement: n-a
raison: "ICMP « fragmentation nécessaire » sortant : c'est ainsi que nos hôtes signalent l'overlay à 1450 aux correspondants distants."
- sens: egress
port: 123
protocole: udp

View file

@ -33,7 +33,10 @@ REGISTRE = RACINE / "docs" / "registre-flux.md"
INSTANCE = Path(os.environ.get("SETOPS_INSTANCE") or (RACINE / "instance"))
SENS = {"ingress", "egress"}
PROTO = {"tcp", "udp"}
# `icmp` n'a pas de port : le champ `port` porte alors le TYPE (ex. `frag-needed`).
# Sans lui, la decouverte de MTU de chemin ne peut pas etre DECLAREE — et une bordure
# en default-deny la casse en silence des que l'overlay descend sous 1500.
PROTO = {"tcp", "udp", "icmp"}
CHIFFREMENT = {"tls-requis", "tls", "starttls", "ssh", "tls-cible", "clair", "n-a"}
MOTS_PAIR = {"edge", "flotte", "externe", "localhost", "expositions", "derive"}
GROUPE_EDGE = "serveur_nginx"