2026-09-01 22:16:20 -04:00
|
|
|
---
|
|
|
|
|
# CE RÔLE EN EXIGE UN AUTRE, ET C'EST À ANSIBLE DE LE SAVOIR.
|
|
|
|
|
#
|
|
|
|
|
# `serveur_backup_site` n'installe rien : il MARQUE un dépôt comme celui où les
|
|
|
|
|
# écosystèmes du site déposent leur état, et vérifie qu'il est réellement en mesure de le
|
|
|
|
|
# recevoir. Pour cela il lit les variables de `serveur_backup`.
|
|
|
|
|
#
|
|
|
|
|
# Les valeurs par défaut d'un rôle ne sont en portée que DANS LE PLAY QUI L'INCLUT. Une
|
|
|
|
|
# dépendance de rôle règle les deux choses d'un coup : Ansible applique l'installateur
|
|
|
|
|
# AVANT le marqueur, dans le MÊME play, donc ses variables sont en portée — et l'ordre
|
|
|
|
|
# cesse de dépendre de la façon dont on lance le déploiement.
|
|
|
|
|
#
|
|
|
|
|
# Même raisonnement que `serveur_cache_site`, `serveur_forge_site` et
|
|
|
|
|
# `serveur_resolveur_site`.
|
|
|
|
|
dependencies:
|
|
|
|
|
# EN PARAMÈTRE, PAS EN `defaults` — mesuré ici même le 2026-09-01.
|
|
|
|
|
#
|
|
|
|
|
# Une dépendance s'exécute AVANT le rôle qui la déclare, et les `defaults` du rôle
|
|
|
|
|
# dépendant ne sont pas encore en portée quand elle tourne. La valeur posée dans
|
|
|
|
|
# `serveur_backup_site/defaults` était donc lue par tout le monde SAUF par le rôle
|
|
|
|
|
# qu'elle visait. Passée ici, elle porte — c'est le seul endroit où elle porte.
|
|
|
|
|
#
|
|
|
|
|
# CE DÉPÔT NE PEUT PAS OUVRIR CE QU'IL GARDE, ET C'EST LE BUT. Les instantanés sont
|
|
|
|
|
# chiffrés par restic CHEZ LE LOCATAIRE, avec un mot de passe qui ne quitte jamais sa
|
|
|
|
|
# voûte. Le site héberge des octets opaques : il ne peut ni les lire, ni les ouvrir,
|
|
|
|
|
# ni les reconstituer. C'est la propriété qui rend la mutualisation acceptable — la
|
|
|
|
|
# même frontière que pour les voûtes : le site sert, il ne sait pas.
|
|
|
|
|
#
|
|
|
|
|
# La vérification n'est pas supprimée, elle est DÉPLACÉE chez celui qui peut
|
|
|
|
|
# l'exercer : le locataire, qui détient la clé et sait ce qu'il a envoyé.
|
|
|
|
|
- role: serveur_backup
|
supervision du site, et la panne qui dormait dans un mot
Le site a son temoin : site-mon-01 (VLAN 36) porte PostgreSQL, Icinga et un
relais. Le depot lui rapporte, et son premier verdict fut un vrai defaut —
site-mon-01 n avait jamais depose son propre etat. Les trois sont au vert.
serveur_backup_verification_locale repasse a true sur le depot : le drapeau ne
dit plus on renonce mais verifie ce que tu peux ouvrir . La liste des noeuds
attendus derive de l inventaire ou tourne le role, donc du site seul.
serveur_postfix gagne un mode relais : un site n heberge aucune boite, il
expedie. Directement par sa frontiere — emprunter le MTA d un locataire ferait
dependre l hebergeur d un ecosysteme qu il peut outvivre.
LA PANNE DE FOND : le modele de routes OPNsense lit enabled ; on lui envoyait
disabled=0, un champ ignore. enabled restait a son defaut, ETEINT. Chaque route
creee par Set-OPS depuis l origine l etait desactivee — invisible, parce qu une
route eteinte EXISTE dans le modele et compte posee . Le rechargement lance
pour activer la nouvelle patte a fait reprendre au noyau sa table depuis le
modele : 14 routes sur 15 disparues, 11 machines de Chezlepro injoignables le
lendemain de sa reconstruction, et le devis toujours vert.
Trois corrections empilees : la cause (enabled), la cecite (le plan lit la table
du NOYAU et signale absent ou eteint), l inaction (la reconfiguration ne se
declenchait que sur un changement du modele).
Aussi : un role du site peut enfin en appeler un autre a travers la frontiere —
le devis traitait tout pair nomme comme l exterieur . Et nftables_admin_ssh se
DERIVE de la carte : recopie a la main, il retardait d une zone, et m a
verrouille dehors de la machine que je venais de creer.
Reste ouvert : le destinataire des alertes est encore root@localhost.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
2026-09-02 17:34:01 -04:00
|
|
|
# `true` DEPUIS QUE LE SITE A UN TEMOIN (2026-09-02).
|
|
|
|
|
#
|
|
|
|
|
# Ce drapeau a longtemps valu `false`, et pour une raison juste : le depot ne peut
|
|
|
|
|
# pas ouvrir les depots des LOCATAIRES — restic chiffre chez eux, avec un mot de
|
|
|
|
|
# passe qui ne quitte pas leur voute. Mais il ne verifiait alors RIEN, y compris ce
|
|
|
|
|
# qu'il pouvait parfaitement ouvrir.
|
|
|
|
|
#
|
|
|
|
|
# `serveur_backup_noeuds_attendus` derive de l'INVENTAIRE OU TOURNE LE ROLE. Ici
|
|
|
|
|
# c'est celui du site : la liste ne contient donc que des machines du site, dont ce
|
|
|
|
|
# depot detient le mot de passe restic — la meme voute. Il verifie exactement ce
|
|
|
|
|
# qu'il peut ouvrir, et reste aveugle au reste. C'etait deja vrai avant ; ce qui
|
|
|
|
|
# manquait, c'etait quelqu'un a qui le dire.
|
|
|
|
|
serveur_backup_verification_locale: true
|
2026-09-01 22:16:20 -04:00
|
|
|
# LE SITE N'HABITE PAS LA RACINE DE SON PROPRE DÉPÔT.
|
|
|
|
|
#
|
|
|
|
|
# `serveur_backup` donne au compte `restic` la racine des dépôts pour home. C'est
|
|
|
|
|
# juste chez un écosystème : il n'y a qu'un déposant, la racine EST son home.
|
|
|
|
|
#
|
|
|
|
|
# Ici il y en a plusieurs, et la racine devient le PARENT de leurs homes. Elle ne
|
|
|
|
|
# peut donc appartenir à aucun d'eux — mesuré le 2026-09-01 : `/srv/restic` en 0700
|
|
|
|
|
# au compte `restic`, sshd a refusé `restic-chez` par `StrictModes`, qui exige que
|
|
|
|
|
# chaque répertoire menant au home appartienne à root ou à l'utilisateur lui-même.
|
|
|
|
|
# Le message rendu était « Permission denied (publickey) » — celui d'une mauvaise
|
|
|
|
|
# clé. La clé était la bonne ; c'est le CHEMIN qui était refusé. Rien dans ce
|
|
|
|
|
# message ne pouvait le dire.
|
|
|
|
|
#
|
|
|
|
|
# Le site prend donc un sous-répertoire comme tout le monde. Le parent est à root,
|
|
|
|
|
# traversable et non listable : voir `serveur_backup_site_parent`.
|
|
|
|
|
serveur_backup_racine: "/srv/restic/site"
|
|
|
|
|
|
durcissement : le site recoit enfin serveur_durci
Les six machines du SITE — racine de l AC, forge, cache, resolveur, depot de
sauvegarde, runner — ne recevaient que serveur_debian. Ni auditd, ni fail2ban,
ni apparmor, ni sysctl, ni pare-feu. Le commentaire au-dessus de GROUPE_SOCLE
affirmait pourtant le contraire, ce qui rendait l ecart invisible.
Le pare-feu du site n avait aucune des trois pieces qui le rendent applicable :
- aucune regle generee (resoudre_flux lit un hosts.yml ; le site a un inventaire
dynamique) -> commande nftables-site, branchee sur make flux
- le chemin du jeu de regles sortait du depot (inventory_dir vaut scripts/ pour
un inventaire dynamique) -> host_var explicite
- aucun nftables_admin_ssh : l exploitant administre PAR REBOND, la connexion
arrive avec l adresse de la patte de frontiere DANS LA ZONE VISEE. Le
generateur refuse desormais de produire des regles sans cet intrant.
Defaut attrape en LISANT le jeu de regles avant de l appliquer : la regle DNS de
site-dns-01 omettait 10.17.0.0/16. _supernets_voisins retire l instance montee —
juste chez un tenant, faux du cote du site, ou ca retire le locataire qu on
pilote. L appliquer aurait prive de DNS les quinze machines reconstruites la
veille.
MaxStartups du depot passe en host_var : dans le meta du role, il ne portait que
dans son play, et le passage de serveur_durci le remettait au defaut sans rien
dire. Un reglage qui depend de l ordre des plays revient en arriere.
Verifie depuis un locataire a travers le nouveau pare-feu : cache, forge, depot
(2 snapshots) et resolveur repondent ; l AC du site refuse, et c est correct.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
2026-09-02 10:31:21 -04:00
|
|
|
# SSH DURCI COMME PARTOUT AILLEURS. Le desserrage que ce depot exige ne se declare PAS
|
|
|
|
|
# ici : voir `serveur_backup_site_max_startups` dans `site_inventaire.py`, et pourquoi.
|
2026-09-01 22:16:20 -04:00
|
|
|
- role: ssh_hardening
|