La revision a commence par un balayage par motifs — chemins morts, cibles make absentes, comptes derives. Il a trouve une trentaine d ecarts et rate presque tout le reste : un motif ne voit que ce qui s exprime en motif. make hote-planifier en est l exemple. La cible EXISTE, donc le controle passait au vert. C est une cible depreciee qui refuse et sort en 2, recommandee par AGENTS.md, et qui contredit la REGLE D OR du meme fichier trois ecrans plus haut. Il fallait lire pour la voir. 74 documents lus un par un. 66 corriges, 8 exacts. CE QUI ETAIT FRANCHEMENT FAUX AGENTS.md, la source d autorite, annoncait la flotte pas encore executee contre des VM reelles. Elle a ete rasee et remontee depuis zero trois fois. ecosysteme-chezlepro.md, le document montre a un client, portait la meme phrase : il se sous-vendait gravement. courriel-conception.md s ouvrait sur aucun role n est encore ecrit, au-dessus de son propre paragraphe 1 qui les nomme. autorisation.md se terminait sur rien n est construit alors qu il rapporte des mesures datees du role en fonctionnement. hebergeur-exploitation.md disait rien n est fait d un depot qui existe. filiation-emancipation.md se contredisait a deux ecrans de distance. DES MODELES DECRITS D APRES UN MONDE ANTERIEUR Le resolveur : cinq documents decrivaient un Unbound par VM en opt-in, trois le donnaient en exemple d integration FACULTATIVE — il est universel depuis le 2026-08-24. L adressage de nomenclature-vm.md : reseau unique, VLAN 11-15, VMID a cinq chiffres. Le nommage SDN de sdn-evpn.md contre le code : c est le wiki qui avait raison. CE QUI CASSE AU PREMIER ESSAI Le nom du gabarit dore etait faux a quatre endroits, dont la procedure qui le FABRIQUE et le critere R2 de l epreuve d operateur independant. preparer-un-site-hebergeur.md avertissait qu une VM faite a la main serait detruite : raser derive du plan, il ne la detruira jamais — le risque est l inverse. Un mot de passe d essai en clair dans un depot public. DEUX PREUVES ETENDUES, ET UNE QUI SE TROMPAIT ELLE-MEME P57 couvre les groupes : elle a signale aussitot 29 groupes annonces au-dessus d un tableau qui en cite 40. P29 confronte le tableau de authentification.md aux declarations reelles : 12 annonces, 21 reels. Et P57 imposait un chiffre faux — 56 preuves alors que le depot en porte 57, la conditionnelle vivant hors de tout comptage. Un garde-fou qui fait respecter une erreur ajoute l assurance a l erreur. CE QUI RESTE, ET QU AUCUNE PREUVE NE TIENT Deux comptes trouves a la main. Et une lacune reelle : rien ne garde les meta/acces.yml — ni qu un service web-sso en porte un, ni que le groupe qu il nomme existe. P29 tient les positions d authentification, personne ne tient les habilitations. make prouver : CONFORME, 56 OK, 0 echec, 1 saute. 0 lien mort. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
11 KiB
Runbooks d'exploitation — Set-OPS
Pour qui : l'exploitant, face à une situation. Pas le mainteneur, pas l'apprenant. Le pourquoi vit dans les autres
docs/; la version pédagogique, dans le wiki. Ici, uniquement le comment faire.Tu viens de reprendre l'écosystème et tu ne sais pas par où entrer ? Wiki → Reprendre l'écosystème.
1. Un certificat a expiré / le login SSO est cassé
Symptôme : connexion à une app via le SSO échoue après le login ; log Grafana/app :
tls: failed to verify certificate: x509: certificate has expired.
Cause fréquente : le cert step-ca a été renouvelé sur disque mais le service (nginx sur l'edge) n'a pas été rechargé → il sert l'ancien cert en mémoire.
Diagnostic-réflexe — comparer le cert servi au cert fichier :
# SERVI (en mémoire par nginx)
echo | openssl s_client -connect infra-edge-01.chezlepro.internal:443 -servername keycloak.chezlepro.internal 2>/dev/null \
| openssl x509 -noout -enddate
# FICHIER (sur disque)
openssl x509 -in /etc/step/certs/infra-edge-01.chezlepro.internal.crt -noout -enddate
Dates différentes (servi < fichier) ⇒ nginx sert un cert périmé.
Fix immédiat : systemctl reload nginx sur l'edge (idem postfix/dovecot/slapd selon le
service touché).
Fix permanent (déjà en place) : client_pki_reload_services recharge les vrais consommateurs
après chaque renouvellement — edge→nginx, mail→postfix/dovecot, annuaire→slapd. Vérifier :
systemctl cat cert-renewer@$(hostname -f).service | grep ExecStartPost.
Voir aussi l'unité wiki PKI & confiance (⑤ le renouvellement).
2. Donner Explore/Editor à un opérateur dans Grafana (RBAC)
Par défaut, un utilisateur SSO est Viewer (dashboards seulement, pas Explore). Pour l'élever :
- Déclarer l'assignation dans l'inventaire de l'instance (group_vars
serveur_keycloak) :serveur_keycloak_role_assignments: - { user: <uid>, role: grafana-editor } # ou grafana-admin - Redéployer Keycloak (
make deployersur le nœud SSO) — kcadm à chaud, sans coupure. - L'utilisateur doit se déconnecter/reconnecter (Grafana applique le rôle à la connexion).
Mapping (défaut du rôle grafana) : grafana-admin→Admin, grafana-editor→Editor, sinon Viewer
(serveur_grafana_oidc_role_path).
Préférer le groupe à la personne — et c'est construit, pas un idéal. Les groupes LDAP sont projetés dans Keycloak et émis en claim (
tasks/groupes-ldap.yml,claim-groupes.yml), etroles/serveur_grafana/meta/acces.ymldéclare déjàsysadmin ⇒ Admin,personnel ⇒ Viewer. Ajouter quelqu'un au groupe lui ouvre Grafana, Forgejo, Icinga et le courriel d'un seul geste — alors qu'une assignation nominative crée une dette qu'on découvre le jour du départ, service par service. L'assignation explicite ci-dessus reste le geste de dépannage, pas la façon normale d'accorder un accès. Voirdocs/autorisation.md§5.
3. « Connection timed out during banner exchange » — le message qui accuse le réseau
Symptôme : Ansible marque un ou plusieurs hôtes injoignables, avec ce message. On soupçonne le réseau, la route ou le pare-feu. C'est presque toujours autre chose.
Pourquoi le message trompe. À travers la frontière, la poignée TCP aboutit toujours — le
pare-feu y répond lui-même sans relayer (voir frontiere-opnsense.md). L'échec ne peut donc
pas se présenter comme un « connection refused » franc : il se manifeste plus tard, au moment
où le serveur devrait annoncer sa bannière SSH. D'où un message qui parle de délai réseau pour
un hôte qui, souvent, n'a jamais rien reçu.
Les trois causes, par fréquence :
- La VM n'est pas encore là.
make creer-vmrend la main dès que Proxmox a démarré la VM, pas quand elle répond. C'est le cas normal, quotidien, et aucun correctif ne l'abolira : les attentes actives duMakefileexistent pour ça. sshdrefuse une rafale.MaxStartups/MaxSessionstrop serrés coupent des connexions parfaitement légitimes — deux déploiements interrompus le 2026-08-09, sur des hôtes qui n'avaient ni redémarré ni perdu leur réseau. Réglés parssh_hardening_max_startups(10:30:60) etssh_hardening_max_sessions(10), avec l'arbitrage expliqué dansroles/ssh_hardening/defaults/main.yml.- Le réseau, vraiment — le cas le plus rare, et le dernier à examiner.
Ce qui tranche, dans l'ordre :
make hote-afficher HOTE=<nom> # l'hôte existe-t-il au plan ?
ssh -v ansible@<ip> 2>&1 | tail -20 # où la négociation s'arrête exactement
Une bannière (SSH-2.0-OpenSSH…) prouve que le chemin est bon et que le problème est
applicatif. Aucun connect() ne prouvera quoi que ce soit ici — il réussit vers le vide.
4. Brander une instance Forgejo (identité visuelle)
Activer dans l'inventaire (group_vars serveur_forgejo) :
serveur_forgejo_branding: true
serveur_forgejo_app_name: "Forge Chezlepro"
serveur_forgejo_theme: "forgejo-dark"
serveur_forgejo_meta_description: "…"
Puis redéployer. Le rôle déploie le dossier custom/ officiel (logo/favicon aurore, accent CSS par
variables, page d'accueil brandée) — léger, résistant aux MAJ (aucune classe interne touchée).
Note : ne s'applique qu'aux Forgejo gérées par Set-OPS.
5. Restaurer — et d'abord : prouver qu'on peut
Éprouvé le 2026-08-12 sur Chezlepro.
make validerrejoue la partie automatisable ; la restauration d'une base reste manuelle, et porte un piège décrit plus bas.
Ce que make valider prouve tout seul, pour chaque nœud détenteur d'état : le dernier
instantané se restaure, il en sort des fichiers, et — pour l'annuaire — qu'il est
rejouable (slapadd -u, essai à blanc, rien n'est écrit). Verdicts possibles :
| Verdict | Sens |
|---|---|
OK |
restauré, et non vide |
À CONFIRMER |
restauré, mais l'instantané n'emporte aucun fichier — légitime si ce nœud n'a pas encore de données, à trancher par un humain |
SANS OBJET |
ce nœud ne détient rien de non régénérable |
ÉCHEC |
la restauration elle-même a échoué |
Restaurer les clés de l'autorité (infra-pki-01)
export RESTIC_REPOSITORY=$(grep -oP 'RESTIC_REPOSITORY="\K[^"]+' /usr/local/sbin/setops-sauvegarder.sh)
export RESTIC_PASSWORD_FILE=/etc/setops/restic.pass
t=$(mktemp -d); restic restore latest --target "$t"
diff -r "$t/etc/step-ca" /etc/step-ca
Mesuré : 12 fichiers, 11 identiques octet pour octet, root_ca_key et
intermediate_ca_key compris. Le seul écart attendu est db/000000.vlog — le journal de
la base badger de step-ca, qui avance à chaque émission de certificat.
Rejouer une base depuis pg_dumpall — LE PIÈGE
pg_dumpall écrit CREATE DATABASE <suivante> avant le \connect correspondant.
Découper « du \connect X au \connect suivant » emporte donc un ordre qui vise une
autre base. Couper aussi sur CREATE DATABASE, et vérifier avant de rejouer :
awk '/^\\connect forgejo$/{f=1;next} f && (/^\\connect /||/^CREATE DATABASE /){exit} f' \
toutes-bases.sql > section.sql
grep -qE '^(DROP|CREATE|ALTER) DATABASE|^\\connect' section.sql \
&& { echo "REFUS : ordre hors-perimetre"; exit 1; }
runuser -u postgres -- createdb epreuve_restauration
runuser -u postgres -- psql -q -d epreuve_restauration -f section.sql
runuser -u postgres -- psql -tAd epreuve_restauration -c "select count(*) from information_schema.tables where table_schema='public'"
runuser -u postgres -- dropdb epreuve_restauration
Mesuré sur forgejo : rejeu en 0 erreur, 130 tables, et les comptes réels
(forgejo-admin, sysadmin). Production vérifiée intacte après coup.
Ne jamais rejouer un pg_dumpall entier sur un cluster vivant : il contient les
DROP DATABASE de toutes les bases. Une restauration réelle se fait sur un cluster neuf.
6. La bascule d'adressage de la fabric (D-77) — FAITE
Cette section décrivait une transition en cours jusqu'au 2026-09-06. Elle est terminée : mesuré le 2026-08-22,
10.0.0.0/24n'existe plus — ni10.0.0.1, ni10.0.0.41ne répondent. Le plan d'administration est10.17.0.0/24: la frontière y répond en10.17.0.1sur un port physique à elle, les commutateurs sont en10.17.0.3et.4avec cette passerelle par défaut, le poste de l'exploitant en10.17.0.17. Le renumérotage du tenant (10.27→10.17) est fait lui aussi.On garde la méthode, parce qu'elle est ce qui a permis de le faire sans coupure, et qu'un autre site la rejouera :
Ajouter avant de retirer, jamais l'inverse. Un point de routage qui change d'adresse d'un coup coupe simultanément l'exploitant, les commutateurs qui l'ont en passerelle par défaut, et l'outil qui devait faire la bascule. La seconde adresse a donc vécu à côté de l'ancienne (
ipalias), et l'ancienne n'est tombée qu'en dernier.Distinguer une destination d'un chemin (D-78). Un réseau qui n'est jamais une destination — seulement un chemin — n'a aucune raison d'être unique entre deux hébergeurs : il sort de l'espace dérivé, vers
192.168.<vlan>.0/24. Seule la gestion doit rester unique d'un site à l'autre, parce que le poste de l'exploitant, un VPN et demain un lien inter-sites doivent l'atteindre.Appliqué pour le transport VXLAN seulement, à ce jour (mesuré le 2026-09-06) :
underlay-vxlanest bien en192.168.50.0/24. Le transit (10.0.4.0/24, VLAN 40) et le stockage (10.11.5-7.x, VLAN 5/6/7) sont encore dans l'ancien espace. Ce n'est pas une urgence — ces réseaux ne quittent jamais leur site — mais la carte doit dire ce qui est, pas ce qui a été décidé. Un site neuf se monte directement au schéma final : il n'a aucune transition à subir.Un plan d'adressage ne doit pas dépendre de l'ordre d'une migration. Le VLAN de transport est passé de 11 à 50 — non parce que 11 était mauvais, mais parce que
192.168.11.0/24est occupé par le contrôle de la grappe. Faire dépendre un plan d'adressage de l'ordre d'une migration est exactement la dette qui se paie un an plus tard.
Ce qui reste, et qui n'est PAS un reliquat de la bascule
Les hyperviseurs gardent deux plans, et c'est voulu :
| Plan | Réseau | Ce qu'il porte |
|---|---|---|
| administration | 10.17.0.0/24 (vmbr3, segment physique) |
les équipements et l'exploitant ; aucune VM ne peut y naître (aucun pont ne le touche, et le validateur refuse qu'on y déclare une machine) |
| contrôle de la grappe | 192.168.11.0/24 (vmbr0, carte dédiée) |
l'interface web Proxmox et le dialogue entre nœuds — c'est par là qu'on atteint ansible@192.168.11.4x |
Le
/24de gestion vit à l'intérieur du/16du tenant, et ce n'est pas un conflit. Les zones d'un tenant commencent au 3ᵉ octet 16 ; la bande 0-15 est libre pour la fabric, et la route connectée du/24est plus spécifique que celle du/16— la règle du préfixe le plus long, pas une coïncidence. Il faut cependant le déclarer (bande_basse_de:dansunderlay.yml), sinon le validateur ne peut pas distinguer ce chevauchement voulu d'un chevauchement accidentel.