frontiere : ne router que les sous-reseaux REELLEMENT attribues
Router 10.27.0.0/16 entier faisait porter a la frontiere des destinations qui n'existent nulle part. Ces paquets atteignaient le noeud de sortie, y arrivaient dans la table PRINCIPALE — pas dans le VRF, qui n'est atteint que par les /24 annonces en BGP — et repartaient vers la passerelle du reseau d'ADMINISTRATION. Mesure : ip route get 10.27.99.99 rendait via 192.168.11.254. C'est aussi ce qui faisait reussir tout connect() depuis le VLAN d'administration, y compris vers des adresses inexistantes — symptome attribue pendant deux jours a une fonction d'anti-usurpation de la frontiere, alors que c'etait un routage trop large. Le devis emet desormais une route par sous-reseau attribue (12 au lieu de 2). Le NAT reste sur le supernet : il porte sur la SOURCE, qui contient tous les sous-reseaux — la garde P24 itere sur les alias et reste satisfaite. Verifie avant de livrer : les 14 hotes du plan sont tous dans les six /24, aucun ne serait coupe. L'applicateur ne gere pas les routes (0 mention) : le devis prescrit, l'exploitant applique — D-23/D-24, et ce chemin est celui de son administration. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
78f2f7fd6f
commit
df05d90059
2 changed files with 24 additions and 7 deletions
|
|
@ -36,7 +36,7 @@
|
||||||
| P21 | Federation : aucun index en collision | AFF-102 | ✅ OK | Federation coherente : 2 instance(s) federee(s), aucun index en collision. |
|
| 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 (20 sections). |
|
| P22 | Plan de recette a jour (genere du wiki) | AFF-002 | ✅ OK | Plan de recette à jour (20 sections). |
|
||||||
| P23 | Underlay sans collision avec la plage tenant | AFF-103 | ✅ OK | Underlay conforme : 6 reseau(x), aucune collision avec la plage tenant. |
|
| P23 | Underlay sans collision avec la plage tenant | AFF-103 | ✅ OK | Underlay conforme : 6 reseau(x), aucune collision avec la plage tenant. |
|
||||||
| P24 | Frontiere nord/sud : acces d'administration declare | AFF-104 | ✅ OK | CONFORME : frontiere nord/sud, 31 regles, 2 routes, admin=10.0.0.0/24,192.168.254.2/32,192.168.255.2/32. |
|
| P24 | Frontiere nord/sud : acces d'administration declare | AFF-104 | ✅ OK | CONFORME : frontiere nord/sud, 31 regles, 12 routes, admin=10.0.0.0/24,192.168.254.2/32,192.168.255.2/32. |
|
||||||
| P25 | Pare-feu Proxmox : est-ouest intra-tenant derive | AFF-107 | ✅ OK | CONFORME : pare-feu Proxmox, 2 tenant(s), 38 groupe(s), 64 regle(s). |
|
| P25 | Pare-feu Proxmox : est-ouest intra-tenant derive | AFF-107 | ✅ OK | CONFORME : pare-feu Proxmox, 2 tenant(s), 38 groupe(s), 64 regle(s). |
|
||||||
| P26 | Integrations universelles : aucun hote laisse de cote | AFF-108 | ✅ OK | 14 hote(s) x 4 integration(s) universelle(s) : aucune lacune, aucune recopie (1 exemption(s) derivee(s) du service rendu). |
|
| P26 | Integrations universelles : aucun hote laisse de cote | AFF-108 | ✅ OK | 14 hote(s) x 4 integration(s) universelle(s) : aucune lacune, aucune recopie (1 exemption(s) derivee(s) du service rendu). |
|
||||||
| P27 | Propriete des intrants : hebergeur et tenant separes | AFF-109 | ✅ OK | 0 cle(s) de cluster chez l'hebergeur, aucune recopiee dans les group_vars du tenant. |
|
| P27 | Propriete des intrants : hebergeur et tenant separes | AFF-109 | ✅ OK | 0 cle(s) de cluster chez l'hebergeur, aucune recopiee dans les group_vars du tenant. |
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ import yaml
|
||||||
RACINE = Path(__file__).resolve().parents[1]
|
RACINE = Path(__file__).resolve().parents[1]
|
||||||
sys.path.insert(0, str(RACINE / "scripts"))
|
sys.path.insert(0, str(RACINE / "scripts"))
|
||||||
|
|
||||||
from inventory_rules import supernet_de # noqa: E402
|
from inventory_rules import sous_reseau_de, supernet_de # noqa: E402
|
||||||
# Helpers internes du resolveur de flux : reutilises VOLONTAIREMENT plutot que
|
# Helpers internes du resolveur de flux : reutilises VOLONTAIREMENT plutot que
|
||||||
# redupliques ici — le registre des flux et l'inventaire doivent avoir une seule
|
# redupliques ici — le registre des flux et l'inventaire doivent avoir une seule
|
||||||
# lecture, sinon le devis et les nftables divergeraient en silence.
|
# lecture, sinon le devis et les nftables divergeraient en silence.
|
||||||
|
|
@ -392,16 +392,33 @@ def construire(tenants: list[tuple[str, str, dict]]) -> dict:
|
||||||
intrants = intrants_frontiere()
|
intrants = intrants_frontiere()
|
||||||
transit = transit_underlay()
|
transit = transit_underlay()
|
||||||
saut = prochain_saut(transit)
|
saut = prochain_saut(transit)
|
||||||
|
# UNE ROUTE PAR SOUS-RESEAU REELLEMENT ATTRIBUE, et non une par supernet.
|
||||||
|
#
|
||||||
|
# Router le /16 entier faisait porter a la frontiere des destinations qui n'existent
|
||||||
|
# nulle part. Ces paquets atteignaient le noeud de sortie, y arrivaient dans la table
|
||||||
|
# PRINCIPALE — pas dans le VRF, qui n'est atteint que par les /24 annonces en BGP — et
|
||||||
|
# repartaient vers la passerelle du reseau d'ADMINISTRATION. Mesure du 2026-08-09 :
|
||||||
|
# `ip route get 10.27.99.99` rendait `via 192.168.11.254`.
|
||||||
|
#
|
||||||
|
# C'est aussi ce qui faisait reussir tout `connect()` depuis le VLAN d'administration,
|
||||||
|
# y compris vers des adresses inexistantes — symptome que nous avons attribue pendant
|
||||||
|
# deux jours a une fonction d'anti-usurpation de la frontiere, alors que c'etait un
|
||||||
|
# routage trop large.
|
||||||
|
#
|
||||||
|
# La frontiere ne route desormais QUE ce qui existe. Le NAT, lui, reste sur le supernet
|
||||||
|
# (alias `SETOPS_TENANT_*`) : il porte sur la SOURCE, et le supernet contient tous les
|
||||||
|
# sous-reseaux — la garde P24 reste donc satisfaite.
|
||||||
|
_sdn = underlay_mod.routage_tenants(underlay_mod.charger()) == "sdn"
|
||||||
routes = [
|
routes = [
|
||||||
{
|
{
|
||||||
"reseau": supernet_de(n["index"]),
|
"reseau": sous_reseau_de(n["index"], int(z)),
|
||||||
"prochain_saut": saut,
|
"prochain_saut": saut,
|
||||||
"description": f"{nom} (index {n['index']}) — routage inter-zone "
|
"description": f"{nom} — {cat.get('libelle', f'zone{z}')} (zone {z}, index "
|
||||||
+ ("dans la zone EVPN du tenant"
|
f"{n['index']}) — " + ("zone EVPN du tenant" if _sdn
|
||||||
if underlay_mod.routage_tenants(underlay_mod.charger()) == "sdn"
|
else "switches L3"),
|
||||||
else "sur les switches L3"),
|
|
||||||
}
|
}
|
||||||
for nom, _pfx, n in tenants
|
for nom, _pfx, n in tenants
|
||||||
|
for z, cat in sorted((n.get("categories") or {}).items(), key=lambda x: int(x[0]))
|
||||||
]
|
]
|
||||||
|
|
||||||
# NAT sortant : une regle par tenant, source = son alias de supernet, cible = l'adresse
|
# NAT sortant : une regle par tenant, source = son alias de supernet, cible = l'adresse
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue