l edge servait du snakeoil, et deux ecritures d une meme regle
Le certificat bouchon de Debian sur les trois noms. serveur_nginx l a pour defaut, avec un commentaire d avant la PKI ; un locataire le remplace en group_vars, l inventaire du site est dynamique et n en a pas. Les autres replis rendaient un service muet — celui-la rend du TLS qui RESSEMBLE a du TLS : le cadenas s affiche et rien n est prouve. site_inventaire construisait sa propre liste d expositions, avec edge = le groupe de l application. Vrai tant que le site n avait pas d edge. client_pki retient un FQDN si son edge est un groupe de cet hote : aucun ne correspondait, et le certificat ne portait que le nom de la machine. La boucle est remplacee par un appel a expositions_des_applications. Et la cicatrice de site-forge-01 — un cert renouvele n atteint personne tant que son consommateur n est pas recharge — a ete refaite sur la machine suivante. Les 6 noms sont maintenant servis et verifies contre l AC du site. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
This commit is contained in:
parent
4f68182ac6
commit
fae3cc8838
2 changed files with 107 additions and 9 deletions
65
CHANGELOG.md
65
CHANGELOG.md
|
|
@ -1,5 +1,70 @@
|
|||
# CHANGELOG — Set-OPS
|
||||
|
||||
## 2026-09-14 (23) — Du TLS qui ressemblait a du TLS, et une regle qu'un tenant n'a jamais eu besoin d'ecrire
|
||||
|
||||
Trois defauts de plus sur le chemin de l'edge, et le premier est le plus grave de la
|
||||
journee.
|
||||
|
||||
### L'edge servait `ssl-cert-snakeoil.pem`
|
||||
|
||||
Le certificat bouchon de Debian, sur les trois noms. `serveur_nginx` l'a pour DEFAUT,
|
||||
avec un commentaire qui date d'avant la PKI : *« a remplacer par des certificats de l'AC
|
||||
interne plus tard »*. Un locataire le remplace dans `group_vars/serveur_nginx.yml` ;
|
||||
l'inventaire du site est DYNAMIQUE et n'a pas de group_vars.
|
||||
|
||||
LES AUTRES REPLIS RENDAIENT UN SERVICE MUET OU UNE REGLE INERTE. Celui-la rend **du TLS
|
||||
qui ressemble a du TLS** : le cadenas s'affiche, la connexion est chiffree, et rien n'est
|
||||
prouve — le certificat n'est signe par personne et ne porte aucun des noms servis. C'est
|
||||
la seule sorte de panne qui rassure.
|
||||
|
||||
### Deux ecritures d'une meme regle, et seule l'une a appris
|
||||
|
||||
`site_inventaire.py` construisait sa PROPRE liste d'expositions, avec `edge` = le groupe
|
||||
de l'application. Le commentaire disait pourquoi : *« le site n'a pas d'edge, donc chaque
|
||||
service se sert lui-meme »*. C'etait vrai jusqu'a hier.
|
||||
|
||||
`client_pki` retient un FQDN si son `edge` est un GROUPE DE CET HOTE. L'edge appartient a
|
||||
`serveur_nginx` ; cette boucle rendait `serveur_grafana`, `serveur_icingaweb2`... Aucun
|
||||
nom ne correspondait. La boucle est remplacee par un appel a
|
||||
`expositions_des_applications` — la regle n'existe plus qu'une fois.
|
||||
|
||||
### La cicatrice refaite sur la machine suivante
|
||||
|
||||
`site-forge-01` porte ce commentaire depuis des semaines : *« Un cert renouvele sur disque
|
||||
reste servi perime tant que le consommateur n'est pas recharge. La cicatrice est deja dans
|
||||
le depot ; on ne la refait pas. »* Elle a ete refaite sur `site-edge-01`, qui n'avait pas
|
||||
de `client_pki_reload_services`.
|
||||
|
||||
disque : forge, pki, dns, sauvegarde, observatoire, vigie, site-edge-01
|
||||
servi : site-edge-01
|
||||
|
||||
### Ou en est l'edge
|
||||
|
||||
certificat servi les 6 noms, signe par l'AC du site
|
||||
verification TLS verif_tls=0 depuis le poste, contre la racine du site
|
||||
vhosts forge, observatoire, vigie — en 443
|
||||
|
||||
### CE QUI RESTE, ET C'EST UNE VRAIE PIECE
|
||||
|
||||
Les trois noms repondent en TLS **verifie**, puis rien : `http=000`. L'edge ne joint pas
|
||||
ses amonts, et le devis le dit lui-meme :
|
||||
|
||||
note : serveur_nginx declare un port `derive` que le plan du site ne resout pas
|
||||
— aucune regle emise.
|
||||
|
||||
`serveur_nginx` declare bien `egress port: derive, pair: expositions`. Ce flux n'a JAMAIS
|
||||
eu besoin d'etre resolu a la frontiere : chez un locataire, les passerelles de zone sont
|
||||
tenues par le SDN de Proxmox, et le trafic edge -> amont ne traverse pas le boitier. **Au
|
||||
site, elles sont tenues par la frontiere** — et c'est le premier endroit ou un edge doit
|
||||
franchir la bordure pour atteindre ce qu'il relaie.
|
||||
|
||||
Resoudre `expositions` en une regle PAR AMONT (son hote, son port) est la piece qui
|
||||
manque. Elle se voit maintenant parce que le site est la premiere fabric ou un edge et
|
||||
ses services vivent dans des zones differentes.
|
||||
|
||||
Et `forge` relaie en `http://10.37.33.11:443` — du clair vers un port TLS, d'ou son `400`.
|
||||
L'amont d'une exposition deja servie en TLS doit etre `https://`.
|
||||
|
||||
## 2026-09-14 (22) — L'edge du site est debout, et quatre replis silencieux l'ont retarde
|
||||
|
||||
`site-edge-01` est nee, deployee, et sert `forge`, `observatoire` et `vigie` en 443. Le
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ from pathlib import Path
|
|||
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
||||
import yaml # noqa: E402
|
||||
import underlay as U # noqa: E402
|
||||
from inventory_rules import expositions_des_applications # noqa: E402
|
||||
from inventory_rules import integrations_universelles # noqa: E402
|
||||
|
||||
# L'inventaire des tenants passe par ce compte ; le site n'a aucune raison d'en differer.
|
||||
|
|
@ -386,15 +387,28 @@ def inventaire() -> dict:
|
|||
# LES EXPOSITIONS : le nom du SERVICE, pas celui de la machine. Un nom de service
|
||||
# survit au demenagement du service ; un nom de machine, non.
|
||||
#
|
||||
# `edge` nomme le GROUPE qui sert ce FQDN — c'est ce qu'attend `hosts_statiques`.
|
||||
# Chez un tenant c'est l'edge nginx, qui termine le TLS pour tout le monde. Le site
|
||||
# n'a pas d'edge : chaque service se sert lui-meme, donc le groupe est le sien. La
|
||||
# forme reste la meme, ce qui la remplit change.
|
||||
expositions: list[dict] = []
|
||||
for nom_app, app in applications.items():
|
||||
for fqdn in (app.get("expose") or []):
|
||||
expositions.append({"fqdn": str(fqdn), "edge": str(app.get("groupe") or ""),
|
||||
"application": nom_app})
|
||||
# `edge` nomme le GROUPE qui sert ce FQDN — c'est ce qu'attend `hosts_statiques`, et
|
||||
# c'est de la que `client_pki` tire les SAN du certificat.
|
||||
#
|
||||
# ON APPELLE LA FONCTION PARTAGEE, ON NE LA REECRIT PLUS (2026-09-14).
|
||||
#
|
||||
# Cette boucle disait : « le site n'a pas d'edge, donc chaque service se sert
|
||||
# lui-meme, donc le groupe est le sien ». C'etait vrai — jusqu'au jour ou le site a
|
||||
# eu un edge. La meme regle vivait alors a DEUX endroits : ici, et dans
|
||||
# `expositions_des_applications`, qui lit le registre des domaines. Seule la seconde
|
||||
# a appris ; celle-ci est restee sur l'ancienne verite.
|
||||
#
|
||||
# CE QUE CA A COUTE. `client_pki` retient un FQDN si son `edge` est un GROUPE DE
|
||||
# CET HOTE. L'edge appartient a `serveur_nginx` ; cette boucle rendait
|
||||
# `serveur_grafana`, `serveur_icingaweb2`... Aucun nom ne correspondait, et le
|
||||
# certificat de `site-edge-01` ne portait QUE celui de la machine — du TLS correct
|
||||
# sur trois noms que personne ne peut appeler.
|
||||
#
|
||||
# Deux ecritures d'une meme regle finissent par diverger. Celle-ci n'existe plus.
|
||||
expositions = expositions_des_applications(
|
||||
{"applications": applications},
|
||||
{"domaines_publics": (U.lire_plan_site("domaines.yml") or {}).get("domaines_publics") or {}},
|
||||
)
|
||||
|
||||
# --- LES GARDES DU PLAN, LA OU LE PLAN EST LU ----------------------------
|
||||
#
|
||||
|
|
@ -666,6 +680,25 @@ def inventaire() -> dict:
|
|||
# un. Les deux autres modes d'Icinga Web 2 (`ldap`, `external`) supposent
|
||||
# l'un ou l'autre ; ici, nginx authentifie et l'application le croit.
|
||||
"serveur_icingaweb2_auth": "locale",
|
||||
# L'EDGE SERT LE CERTIFICAT DE L'AC INTERNE, PAS LE BOUCHON DE DEBIAN.
|
||||
#
|
||||
# `serveur_nginx` a pour DEFAUT `ssl-cert-snakeoil.pem`, avec un commentaire
|
||||
# qui date d'avant la PKI : « a remplacer par des certificats de l'AC interne
|
||||
# plus tard ». Chez un locataire, `group_vars/serveur_nginx.yml` le remplace.
|
||||
# L'inventaire du site est DYNAMIQUE et n'a pas de group_vars : l'edge est
|
||||
# donc ne en servant du snakeoil.
|
||||
#
|
||||
# C'EST LE PLUS GRAVE DES REPLIS DE LA JOURNEE. Les autres rendaient un
|
||||
# service muet ou une regle inerte — celui-la rend du TLS qui RESSEMBLE a du
|
||||
# TLS. Le cadenas s'affiche, la connexion est chiffree, et rien n'est prouve :
|
||||
# le certificat servi n'est signe par personne et ne porte aucun des noms.
|
||||
#
|
||||
# Le chemin est celui que `client_pki` ecrit, et le meme que celui des
|
||||
# locataires — une seule convention, pas deux.
|
||||
"serveur_nginx_certificat":
|
||||
"/etc/step/certs/{{ ansible_fqdn | default(ansible_hostname) }}.crt",
|
||||
"serveur_nginx_cle":
|
||||
"/etc/step/certs/{{ ansible_fqdn | default(ansible_hostname) }}.key",
|
||||
# Le depot du site, pour les machines du site qui y deposent. Vide s'il n'y
|
||||
# en a pas — `client_backup` refuse alors, plutot que de viser un nom qui
|
||||
# ne repond pas : mieux vaut un deploiement qui s'arrete qu'une sauvegarde
|
||||
|
|
|
|||
Loading…
Reference in a new issue