devis switch : le port vers la frontière, et l'ordre d'application
Deux omissions que le devis faisait porter à l'opérateur. Le VLAN de transit était étiqueté sur le trunk `<PORT-VERS-PROXMOX>`, et aucune interface vers le pare-feu n'était émise. Les hyperviseurs n'ont pas d'interface sur le transit, et le pare-feu n'a rien à faire des VLAN tenants — il route vers eux, il ne les étiquette pas. Le transit sort du trunk Proxmox et prend son propre port (section 4b), dérivé de l'underlay. Les routes de la section 5 déplacent la sortie du switch, y compris celle de ses propres réponses. Tant que la frontière ne répond pas, elles coupent l'accès d'administration AU SWITCH LUI-MÊME — le mécanisme qui a rendu une VM muette le 2026-07-29, appliqué à l'équipement depuis lequel on travaille. Le devis les crachait à la suite des autres comme si elles étaient équivalentes ; il énonce maintenant les préalables et l'ordre. Sans transit déclaré, les deux sections s'affichent en clair comme manquantes plutôt que de disparaître. Preuves : 24 OK, 0 échec. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
069e549160
commit
0d64d28402
3 changed files with 65 additions and 1 deletions
20
CHANGELOG.md
20
CHANGELOG.md
|
|
@ -1,5 +1,25 @@
|
||||||
# CHANGELOG — Set-OPS
|
# CHANGELOG — Set-OPS
|
||||||
|
|
||||||
|
## 2026-08-01 (suite 2) — le port vers la frontière, et l'ordre d'application
|
||||||
|
|
||||||
|
### Ajouté — section 4b : le port du switch vers la frontière
|
||||||
|
Le devis étiquetait le VLAN de transit sur le trunk `<PORT-VERS-PROXMOX>` et n'émettait
|
||||||
|
aucune interface vers le pare-feu. Deux erreurs en une : les hyperviseurs n'ont pas
|
||||||
|
d'interface sur le transit, et le pare-feu n'a rien à faire des VLAN tenants — il route vers
|
||||||
|
eux, il ne les étiquette pas. Le VLAN de transit sort donc du trunk Proxmox et prend son
|
||||||
|
propre port, dérivé du transit déclaré.
|
||||||
|
|
||||||
|
### Ajouté — avertissement d'ordre en tête de la section 5
|
||||||
|
Les routes de la section 5 déplacent la sortie du switch, **y compris celle de ses propres
|
||||||
|
réponses**. Tant que l'adresse de la frontière ne répond pas, elles coupent l'accès
|
||||||
|
d'administration au switch lui-même — le mécanisme qui a rendu une VM muette le 2026-07-29,
|
||||||
|
appliqué cette fois à l'équipement depuis lequel on travaille.
|
||||||
|
|
||||||
|
Le devis crachait ces lignes à la suite des autres comme si elles étaient équivalentes.
|
||||||
|
Il énonce désormais les préalables (boîtier câblé, adressé, joignable depuis le switch,
|
||||||
|
session console ouverte) — inacceptable autrement pour un outil censé être exploitable sans
|
||||||
|
IA.
|
||||||
|
|
||||||
## 2026-08-01 (suite) — le prochain saut dérive du transit
|
## 2026-08-01 (suite) — le prochain saut dérive du transit
|
||||||
|
|
||||||
`opnsense_prochain_saut` n'est plus un intrant du panneau : il **dérive** du réseau de
|
`opnsense_prochain_saut` n'est plus un intrant du panneau : il **dérive** du réseau de
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,17 @@ ip route 192.168.255.0 255.255.255.0 10.0.4.2 # retour (nftables_admin_ssh)
|
||||||
**L'aller** est la sortie générale : sans elle, aucun hôte de la flotte n'atteint quoi que ce
|
**L'aller** est la sortie générale : sans elle, aucun hôte de la flotte n'atteint quoi que ce
|
||||||
soit hors de sa zone.
|
soit hors de sa zone.
|
||||||
|
|
||||||
|
### L'ordre d'application, qui n'est pas indifférent
|
||||||
|
|
||||||
|
Les sections 0 à 4b du devis switch sont sûres et posables à tout moment. **La section 5 ne
|
||||||
|
l'est pas.** Ces routes déplacent la sortie du switch — y compris celle de ses propres
|
||||||
|
réponses — vers l'adresse de la frontière. Tant que cette adresse ne répond pas, elles
|
||||||
|
coupent l'accès d'administration **au switch lui-même**.
|
||||||
|
|
||||||
|
C'est le même mécanisme que le piège ci-dessous, mais appliqué à l'équipement depuis lequel
|
||||||
|
on travaille. Préalables, rappelés dans le devis : boîtier câblé, adressé sur le lien de
|
||||||
|
transit, joignable depuis le switch, et une session console ouverte pendant l'opération.
|
||||||
|
|
||||||
**Le retour** est le piège proprement dit. Un paquet d'administration entre par la frontière
|
**Le retour** est le piège proprement dit. Un paquet d'administration entre par la frontière
|
||||||
et atteint la VM ; la réponse part de la VM vers sa passerelle — un SVI **de switch**. Si le
|
et atteint la VM ; la réponse part de la VM vers sa passerelle — un SVI **de switch**. Si le
|
||||||
switch n'a pas de route vers le réseau d'administration, ou s'il l'atteint par un autre chemin
|
switch n'a pas de route vers le réseau d'administration, ou s'il l'atteint par un autre chemin
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,26 @@ def section_underlay(underlay: dict | None) -> list[str]:
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def section_frontiere(transit: dict | None) -> list[str]:
|
||||||
|
"""Port du switch vers le pare-feu de bordure. Porte le VLAN de transit, et lui seul.
|
||||||
|
|
||||||
|
Distinct du trunk vers Proxmox : les hyperviseurs n'ont aucune interface sur le
|
||||||
|
transit, et le pare-feu n'a rien a faire des VLAN tenants — il route vers eux, il
|
||||||
|
ne les etiquette pas.
|
||||||
|
"""
|
||||||
|
if not transit:
|
||||||
|
return ["! ----- 4b. Port vers la frontiere -----",
|
||||||
|
"! Aucun reseau de transit declare dans underlay.yml (cle 'passerelle_sortie')."]
|
||||||
|
return [
|
||||||
|
"! ----- 4b. Port vers la frontiere nord/sud -----",
|
||||||
|
f"! Porte le seul VLAN {transit['vlan']} ({transit['nom']}). En lien dedie,",
|
||||||
|
f"! remplacer par : switchport access vlan {transit['vlan']}.",
|
||||||
|
"interface <PORT-VERS-FRONTIERE>",
|
||||||
|
" switchport mode trunk",
|
||||||
|
f" switchport trunk allowed vlan add {transit['vlan']}",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def section_routes(underlay: dict | None) -> list[str]:
|
def section_routes(underlay: dict | None) -> list[str]:
|
||||||
"""Routes du switch vers la frontiere nord/sud. Vide si aucun transit declare.
|
"""Routes du switch vers la frontiere nord/sud. Vide si aucun transit declare.
|
||||||
|
|
||||||
|
|
@ -104,6 +124,14 @@ def section_routes(underlay: dict | None) -> list[str]:
|
||||||
"!"]
|
"!"]
|
||||||
sortie = transit["passerelle_sortie"]
|
sortie = transit["passerelle_sortie"]
|
||||||
out = ["! ----- 5. Routes vers la frontiere nord/sud -----",
|
out = ["! ----- 5. Routes vers la frontiere nord/sud -----",
|
||||||
|
"! /!\\ A APPLIQUER EN DERNIER, ET SEULEMENT UNE FOIS LA FRONTIERE VIVANTE.",
|
||||||
|
f"! Ces routes deplacent la sortie du switch — y compris celle de ses propres",
|
||||||
|
f"! reponses — vers {sortie}. Tant que cette adresse ne repond pas, elles",
|
||||||
|
"! coupent l'acces d'administration AU SWITCH LUI-MEME.",
|
||||||
|
"! Prealables : boitier cable, adresse sur le lien de transit, et joignable",
|
||||||
|
f"! depuis le switch (ping {sortie} depuis Vlan{transit['vlan']}).",
|
||||||
|
"! Garder une session console ouverte pendant l'operation.",
|
||||||
|
"!",
|
||||||
f"! Transit '{transit['nom']}' (VLAN {transit['vlan']}) : SVI {transit['passerelle']}"
|
f"! Transit '{transit['nom']}' (VLAN {transit['vlan']}) : SVI {transit['passerelle']}"
|
||||||
f" <-> frontiere {sortie}",
|
f" <-> frontiere {sortie}",
|
||||||
"! Aller : sortie generale de la flotte.",
|
"! Aller : sortie generale de la flotte.",
|
||||||
|
|
@ -189,7 +217,11 @@ def generer(tenants: list[tuple[str, str, dict]], dialecte: str | None = None) -
|
||||||
out += remarque(dialecte, "Reste (Internet / inter-tenant controle) -> passerelle OPNsense")
|
out += remarque(dialecte, "Reste (Internet / inter-tenant controle) -> passerelle OPNsense")
|
||||||
out.append(f" permit ip {reseau} {m} any")
|
out.append(f" permit ip {reseau} {m} any")
|
||||||
out += ["!", "! ----- 4. Trunk vers Proxmox + inter-switch (a adapter) -----"]
|
out += ["!", "! ----- 4. Trunk vers Proxmox + inter-switch (a adapter) -----"]
|
||||||
vlans_underlay = [str(r["vlan"]) for r in underlay_mod.reseaux(underlay)]
|
transit = underlay_mod.reseau_transit(underlay)
|
||||||
|
# Le VLAN de transit ne va PAS vers Proxmox : aucun hyperviseur n'a d'interface
|
||||||
|
# dessus. Il sort par le port de la frontiere (ci-dessous), et lui seul.
|
||||||
|
vlans_underlay = [str(r["vlan"]) for r in underlay_mod.reseaux(underlay)
|
||||||
|
if not (transit and r["vlan"] == transit["vlan"])]
|
||||||
vlans_tenants = [
|
vlans_tenants = [
|
||||||
str(vlan_de(n["index"], zone))
|
str(vlan_de(n["index"], zone))
|
||||||
for _, _, n in tenants
|
for _, _, n in tenants
|
||||||
|
|
@ -199,6 +231,7 @@ def generer(tenants: list[tuple[str, str, dict]], dialecte: str | None = None) -
|
||||||
out.append("interface <PORT-VERS-PROXMOX>")
|
out.append("interface <PORT-VERS-PROXMOX>")
|
||||||
out.append(" switchport mode trunk")
|
out.append(" switchport mode trunk")
|
||||||
out.append(f" switchport trunk allowed vlan add {vlans}")
|
out.append(f" switchport trunk allowed vlan add {vlans}")
|
||||||
|
out += ["!"] + section_frontiere(transit)
|
||||||
out += ["!"] + section_routes(underlay)
|
out += ["!"] + section_routes(underlay)
|
||||||
out += ["end", "write memory"]
|
out += ["end", "write memory"]
|
||||||
return "\n".join(out)
|
return "\n".join(out)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue