frontière : les intrants d'interface demandent l'identifiant OPNsense
`opt1`, `igb1` et `TENANTS` désignent le même port — identifiant interne, périphérique FreeBSD, libellé affiché. L'API REST ne parle que du premier. Les libellés des deux intrants ne le disaient pas, et la question s'est posée en pratique. Ils le disent maintenant, et docs/frontiere-opnsense.md explique les trois couches et pourquoi `opt1` est le plus stable : il survit à un changement de carte comme à un renommage. La note « prochain_saut dérive de l'underlay » est repliée dans l'en-tête régénéré par le panneau : une sauvegarde l'effaçait, le fichier étant réécrit depuis le YAML analysé. Vérifié qu'une sauvegarde préserve valeurs et références de voûte. Corrigé au passage : après le renumérotage du /29, deux passages de la doc annonçaient encore 10.0.4.2 comme prochain saut et contredisaient le devis. Preuves : 24 OK, 0 échec. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
7dc7720b4b
commit
9804573f12
4 changed files with 99 additions and 10 deletions
20
CHANGELOG.md
20
CHANGELOG.md
|
|
@ -1,5 +1,25 @@
|
|||
# CHANGELOG — Set-OPS
|
||||
|
||||
## 2026-08-02 — les interfaces se nomment par leur identifiant
|
||||
|
||||
`opt1`, `igb1` et `TENANTS` désignent le même port dans OPNsense : l'identifiant interne, le
|
||||
périphérique FreeBSD et le libellé affiché. L'API REST ne parle que du **premier**, et c'est
|
||||
lui que veulent `opnsense_if_wan` et `opnsense_if_transit`. Le libellé de ces deux intrants ne
|
||||
le disait pas — la question s'est posée en pratique.
|
||||
|
||||
Les libellés le disent maintenant explicitement, et `docs/frontiere-opnsense.md` §6 explique
|
||||
les trois couches ainsi que le motif du choix : `opt1` est le plus stable des trois, il
|
||||
survit à un changement de carte réseau comme à un renommage.
|
||||
|
||||
La note « `opnsense_prochain_saut` dérive de l'underlay » est repliée dans l'en-tête que le
|
||||
panneau régénère : une sauvegarde l'effaçait, puisque le fichier est réécrit depuis le YAML
|
||||
analysé. Vérifié qu'une sauvegarde préserve valeurs **et** références de voûte.
|
||||
|
||||
### Corrigé — la doc portait encore l'ancien plan du `/29`
|
||||
Après le renumérotage (`bifrost-1/-2` en `.1`/`.2`, SVI en `.6`), deux passages de
|
||||
`docs/frontiere-opnsense.md` annonçaient toujours `10.0.4.2` comme prochain saut. La doc
|
||||
contredisait le devis généré ; les `ip route` des deux coïncident désormais.
|
||||
|
||||
## 2026-08-01 (suite 14) — l'empreinte du root CA n'est pas un secret de voûte
|
||||
|
||||
`client_pki` **dérive l'empreinte à chaud** depuis l'autorité (`step certificate
|
||||
|
|
|
|||
60
docs/audit/preuve-2026-08-02.md
Normal file
60
docs/audit/preuve-2026-08-02.md
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
# Preuve de conformite — Set-OPS — 2026-08-02
|
||||
|
||||
> Genere par `make prouver` (`scripts/prouver.py`). **Rejouable** : relancer
|
||||
> reproduit ce rapport. Chaque preuve rejoue l'outillage existant du depot ;
|
||||
> aucune validation n'est reimplementee ici. Voir le mode d'emploi :
|
||||
> [`docs/audit/README.md`](README.md), et le registre trace :
|
||||
> [`docs/audit/affirmations.md`](affirmations.md).
|
||||
|
||||
- **Instance** : `instance` — inventaire `instance/inventories/principal/hosts.yml`
|
||||
- **Verdict** : ✅ CONFORME (24 OK · 0 echec · 0 saute)
|
||||
|
||||
## Preuves
|
||||
|
||||
| # | Preuve | Affirmations | Statut | Detail |
|
||||
|---|---|---|---|---|
|
||||
| P01 | Lint (ansible-lint) | AFF-006 | ✅ OK | |
|
||||
| P02 | Tests unitaires (inventory_host) | — | ✅ OK | 4 tests passes. |
|
||||
| P03 | Diff-vide du plan (inventaire genere) | AFF-001, AFF-004, AFF-030, AFF-031, AFF-032 | ✅ OK | DIFF VIDE : le plan reproduit exactement l'inventaire actuel. Bascule possible. |
|
||||
| P04 | Groupes <-> playbooks homonymes | AFF-008 | ✅ OK | |
|
||||
| P05 | Dependances causales de groupes | AFF-009, AFF-084 | ✅ OK | |
|
||||
| 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, 63 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. |
|
||||
| P13 | Invariants structurels/doctrinaux | AFF-015, AFF-022, AFF-037, AFF-038, AFF-062 | ✅ OK | LICENSE, socle dossier, pas de couches paralleles, SSH clef-only, nftables off : OK. |
|
||||
| P14 | Pas de chemin lab/ code en dur | AFF-097 | ✅ OK | Aucun chemin instance/inventories/lab/group_vars code en dur. |
|
||||
| P15 | Modele public socle valide | AFF-022, AFF-099 | ✅ OK | Modele public socle : domaines/serveurs/applications/bases valides. |
|
||||
| P16 | Inventaire Ansible complet (--list) | AFF-030 | ✅ OK | 14 hotes, 32 groupes (inventaire dechiffre et parse). |
|
||||
| P17 | Tous les modeles d'instance valident | AFF-022, AFF-099 | ✅ OK | Les 1 modele(s) decouvert(s) valident. |
|
||||
| P18 | Gabarit de voute complet | AFF-026 | ✅ OK | Gabarit de voute complet : 24 secret(s) exige(s), tous presents. |
|
||||
| P19 | Le GUI couvre le schema du plan | AFF-002, AFF-095 | ✅ OK | GUI : les 28 champ(s) des plans reels sont editables (2 plan(s) inspecte(s)), registres toleres : nomenclature. |
|
||||
| P20 | Adressage 100% derive du seed (aucun stocke) | AFF-001, AFF-003 | ✅ OK | 2 nomenclature(s) : adressage 100% derive du seed index. |
|
||||
| P21 | Federation : aucun index en collision | AFF-001 | ✅ 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-001 | ✅ OK | Underlay conforme : 5 reseau(x), aucune collision avec la plage tenant. |
|
||||
| P24 | Frontiere nord/sud : acces d'administration declare | AFF-001 | ✅ OK | CONFORME : frontiere nord/sud, 6 regles, 2 routes, admin=192.168.255.0/24. |
|
||||
|
||||
## Couverture des affirmations ✅ du registre
|
||||
|
||||
Chaque affirmation ✅ automatisable est couverte par la preuve indiquee ci-dessus.
|
||||
Les ✅ **structurelles/doctrinales** non rejouables par une commande (ex. AFF-005
|
||||
`make`=aide, AFF-014 ciblage groupe, AFF-024 `instancier-appliquer`, AFF-051 autorite
|
||||
d'AGENTS.md, AFF-073/075 gardes `make`, AFF-090 wiki) ont ete verifiees a l'audit ;
|
||||
elles restent hors du harnais recurrent (rien d'executable a rejouer).
|
||||
|
||||
## Declarations d'intention (⚪ invérifiables localement — assumees)
|
||||
|
||||
Ces affirmations ne sont pas rejouables hors production ; elles sont **assumees**
|
||||
comme declarations d'intention, non comme preuves :
|
||||
|
||||
- **AFF-036** — « testables avec `--check` autant que possible » : verifiable seulement
|
||||
contre une flotte vivante.
|
||||
- **AFF-091** — contenu pedagogique du wiki : affirmations conceptuelles.
|
||||
- **AFF-096** — « GUI 100 % francais » : revue exhaustive des libelles rendus, non automatisee.
|
||||
- **AFF-007** — hote d'exemple `web-frontal-01` : placeholder assume.
|
||||
|
||||
_Rapport genere le 2026-08-02._
|
||||
|
|
@ -113,9 +113,9 @@ Un `/29` plutôt qu'un `/30` : pendant une transition, deux pare-feux cohabitent
|
|||
et un `/30` n'offre que deux adresses. `make underlay` (**preuve P23**) refuse une sortie hors
|
||||
du lien, confondue avec le SVI, sans SVI, ou déclarée deux fois.
|
||||
|
||||
Ce seul bloc alimente **les deux devis** : le `passerelle` (`10.0.4.1`) devient le SVI côté
|
||||
Ce seul bloc alimente **les deux devis** : le `passerelle` (`10.0.4.6`) devient le SVI côté
|
||||
switch *et* le prochain saut des routes tenants côté frontière ; le `passerelle_sortie`
|
||||
(`10.0.4.2`) devient la route par défaut du switch. Le prochain saut n'est donc **pas** un
|
||||
(`10.0.4.1`) devient la route par défaut du switch. Le prochain saut n'est donc **pas** un
|
||||
intrant du panneau — le saisir en doublon rouvrirait la possibilité de deux valeurs
|
||||
contradictoires pour un seul et même lien.
|
||||
|
||||
|
|
@ -124,8 +124,8 @@ contradictoires pour un seul et même lien.
|
|||
`make devis-reseau` émet alors, en section 5 :
|
||||
|
||||
```
|
||||
ip route 0.0.0.0 0.0.0.0 10.0.4.2 # aller
|
||||
ip route 192.168.255.0 255.255.255.0 10.0.4.2 # retour (nftables_admin_ssh)
|
||||
ip route 0.0.0.0 0.0.0.0 10.0.4.1 # aller
|
||||
ip route 192.168.255.0 255.255.255.0 10.0.4.1 # 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
|
||||
|
|
@ -209,9 +209,13 @@ ansible-vault edit instance/inventories/principal/group_vars/all/vault.yml
|
|||
|
||||
- **Le câblage** — le lien de transit est *décidé* (VLAN 40, `10.0.4.0/29`) et le devis
|
||||
switch émet déjà son SVI et ses routes. Reste à figer, une fois le boîtier raccordé, un
|
||||
seul intrant : `opnsense_if_transit`, le nom de l'interface qui porte le VLAN 40 sur le
|
||||
boîtier — la seule valeur que rien ne peut deviner. Le prochain saut, lui, **dérive** du
|
||||
transit (voir §4).
|
||||
seul intrant : `opnsense_if_transit`, l'interface qui porte le VLAN 40 sur le boîtier — la
|
||||
seule valeur que rien ne peut deviner. Le prochain saut, lui, **dérive** du transit (§4).
|
||||
|
||||
**Trois noms désignent le même port dans OPNsense**, et l'intrant en veut un seul :
|
||||
`igb1` est le périphérique FreeBSD, `TENANTS` (ou tout autre libellé) est la description
|
||||
affichée, et `opt1` est l'**identifiant interne** — le seul que parle l'API REST, et le
|
||||
plus stable des trois : il survit à un changement de carte réseau comme à un renommage.
|
||||
- **Le second VPN** — pendant la transition, le VPN d'administration actuel (pfSense) reste
|
||||
en service et OPNsense en montera un second. Son sous-réseau devra être **ajouté à
|
||||
`nftables_admin_ssh`**, sans quoi il sera muet de la même façon.
|
||||
|
|
|
|||
|
|
@ -128,8 +128,8 @@ INTRANTS_SCHEMA = [
|
|||
("proxmox_ponts", "proxmox", "catalogue", "Proxmox", "Ponts réseau disponibles (liste)", "liste"),
|
||||
("opnsense_api_url", "frontiere", "constante", "Frontière", "URL de gestion de la frontière OPNsense (API REST)", "str"),
|
||||
("opnsense_api_verifier_certs", "frontiere", "defaut", "Frontière", "Valider le certificat TLS de la frontière", "bool"),
|
||||
("opnsense_if_wan", "frontiere", "defaut", "Frontière", "Interface WAN", "str"),
|
||||
("opnsense_if_transit", "frontiere", "defaut", "Frontière", "Interface/trunk vers les switches (transit)", "str"),
|
||||
("opnsense_if_wan", "frontiere", "defaut", "Frontière", "Interface WAN — IDENTIFIANT OPNsense (wan), pas le libellé ni le périphérique", "str"),
|
||||
("opnsense_if_transit", "frontiere", "defaut", "Frontière", "Interface de transit — IDENTIFIANT OPNsense (opt1, opt2…), pas « igb1 » ni le libellé affiché", "str"),
|
||||
("underlay_routeur", "fabric", "constante", "Fabric", "Switch qui porte le routage (SVI, ACL, routes) — les autres restent en L2 pur", "str"),
|
||||
("underlay_dialecte", "fabric", "constante", "Fabric", "Dialecte de CLI du commutateur (cisco | binardat)", "str"),
|
||||
("underlay_stp_mode", "fabric", "defaut", "Fabric", "Mode de spanning-tree (rstp | mstp | pvst)", "str"),
|
||||
|
|
@ -585,7 +585,12 @@ def ecrire_intrants(payload: dict) -> None:
|
|||
"# API keys > « + ». Le secret n'est affiche qu'a la creation.\n"
|
||||
"#\n"
|
||||
"# Le boitier est HORS FLOTTE Ansible : on ne fait que piloter son API REST\n"
|
||||
"# depuis le controleur. Cf. docs/frontiere-opnsense.md.\n---\n")
|
||||
"# depuis le controleur. Cf. docs/frontiere-opnsense.md.\n"
|
||||
"#\n"
|
||||
"# Les interfaces se nomment par leur IDENTIFIANT OPNsense (wan, opt1...), celui\n"
|
||||
"# que parle l'API REST — ni le peripherique FreeBSD (igb1), ni le libelle affiche.\n"
|
||||
"# `opnsense_prochain_saut` n'est pas ici : il DERIVE du reseau de transit de\n"
|
||||
"# l'underlay (underlay.yml, cle `passerelle_sortie`). Source unique.\n---\n")
|
||||
if "fabric" in par_fichier:
|
||||
_ecrire_intrants_fabric(par_fichier["fabric"])
|
||||
if "reseau" in par_fichier and "index" in par_fichier["reseau"]:
|
||||
|
|
|
|||
Loading…
Reference in a new issue