Registre des flux : schéma meta/flux.yml + pilote (postgresql/metrique/nginx)

Couche accès du zéro-confiance (complète le chiffrement). Chaque rôle possède
ses flux (comme meta/empreinte) : sens/port/protocole/pair/chiffrement/raison.
Résolu par le plan (pair→IP) → génère les règles nftables (default deny) ET le
registre d'audit. Doc de conception + 3 pilotes validés (résolveur-démo).

Séquence : schéma+pilote (fait) → résolveur → remplir les rôles → générer +
registre → activer nftables prudemment (action destructive).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Daniel Allaire 2026-07-05 09:41:42 -04:00
parent 04d807c78d
commit c98bc8393f
4 changed files with 96 additions and 0 deletions

55
docs/flux-conception.md Normal file
View file

@ -0,0 +1,55 @@
# Registre des flux réseau — conception
## But
Set-OPS tient un **registre des flux** (qui parle à qui, sur quel port, dans quel sens, pourquoi)
pour **deux usages** :
1. **Générer les règles nftables** de chaque serveur — autoriser les flux déclarés, **tout refuser
d'autre** (moindre privilège). Complète la couche *chiffrement* (TLS) par la couche *accès*.
2. **Preuve d'audit** — la matrice d'accès réseau documentée (source → dest : port : chiffrement :
raison), exigée par un audit de sécurité et le label de certification.
## Principe : le rôle possède ses flux
Comme `meta/empreinte.yml` (dimensionnement) est la propriété du rôle, **`roles/<rôle>/meta/flux.yml`**
déclare les flux du logiciel. Le rôle sait sur quoi il écoute et à quoi il se connecte ; personne
d'autre. Le registre global se **dérive** de l'ensemble des `flux.yml` des rôles présents sur un nœud.
## Schéma de `meta/flux.yml`
```yaml
flux:
- sens: ingress # ingress = ce rôle ÉCOUTE ; egress = ce rôle SE CONNECTE
port: 5432 # entier ou liste [80, 443]
protocole: tcp # tcp | udp
pair: [serveur_keycloak, serveur_forgejo] # QUI — voir « Résolution du pair »
chiffrement: tls-requis # tls-requis | tls | starttls | clair | n-a (bonus audit)
raison: "Connexions applicatives (verify-full)." # lisible, pour l'audit
```
### Résolution du `pair`
| Valeur | Résout vers |
|---|---|
| un **rôle/groupe** (`serveur_prometheus`) | les IP des hôtes de ce groupe (via le plan) |
| `edge` | le(s) hôte(s) de l'edge (`serveur_nginx`) |
| `flotte` | tous les nœuds de l'instance |
| `externe` | hors flotte (frontière publique — géré à l'OPNsense, pas dans le nœud) |
| `localhost` | boucle locale — aucune règle inter-nœud (nftables autorise `lo`) |
| `expositions` | dérivé des `expose:` des applications (cas de l'edge → backends) |
La résolution `pair → IP` réutilise le **plan** (registre IP/FQDN/zones) déjà en place.
## Génération
Un **résolveur** (miroir de `instancier`) agrège, par serveur, les `flux.yml` de tous ses rôles
(services + intégrations), résout les `pair`, et produit :
- **`nftables`** : ruleset par serveur (allow des flux résolus, `policy drop` par défaut), consommé
par le rôle `nftables_baseline` ;
- **le registre d'audit** : `docs/registre-flux.md` (généré) + une cible `make flux`.
## Activation prudente
Activer nftables = **action destructive** (peut couper l'accès) → confirmation explicite +
déploiement graduel (garder l'accès SSH/Ansible, tester par nœud). nftables reste *préparé mais
non activé* tant que le registre n'est pas complet et validé.
## Séquence
1. ✅ figer le schéma (ce doc) + **piloter** sur postgresql / client_metrique / nginx ;
2. le **résolveur** (agrégation → règles + registre) ;
3. **remplir** tous les rôles (large transcription du travail zéro-confiance déjà fait) ;
4. **générer** + registre d'audit ; puis **activer** nftables nœud par nœud.

View file

@ -0,0 +1,9 @@
---
# Flux réseau de node_exporter (propriété du rôle). Voir docs/flux-conception.md.
flux:
- sens: ingress
port: 9100
protocole: tcp
pair: serveur_prometheus
chiffrement: tls
raison: "Scrape des métriques par Prometheus (node_exporter en HTTPS)."

View file

@ -0,0 +1,23 @@
---
# Flux réseau de l'edge nginx (propriété du rôle). Voir docs/flux-conception.md.
# Cas « edge » : ingress depuis l'extérieur (frontière publique) + egress vers les backends,
# ces derniers dérivés des `expose:` des applications (pair: expositions).
flux:
- sens: ingress
port: 80
protocole: tcp
pair: externe
chiffrement: clair
raison: "HTTP entrant — redirection permanente vers HTTPS."
- sens: ingress
port: 443
protocole: tcp
pair: externe
chiffrement: tls-requis
raison: "HTTPS entrant — services exposés (terminaison TLS à l'edge)."
- sens: egress
port: derive
protocole: tcp
pair: expositions
chiffrement: tls-cible
raison: "Proxy vers les backends exposés (host:port dérivés des expose ; TLS interne = roadmap edge→backends)."

View file

@ -0,0 +1,9 @@
---
# Flux réseau de PostgreSQL (propriété du rôle). Voir docs/flux-conception.md.
flux:
- sens: ingress
port: 5432
protocole: tcp
pair: [serveur_keycloak, serveur_forgejo, serveur_icinga, serveur_nextcloud]
chiffrement: tls-requis
raison: "Connexions applicatives à PostgreSQL (verify-full ; pg_hba hostssl)."