[infra] Copie des sauvegardes hors du serveur, et outillage d'administration à recâbler #92
Labels
No labels
Compat/Breaking
EC01
EC02
EC03
EC04
EC05
EC06
Kind/BDD
Kind/Back
Kind/Bug
Kind/CICD
Kind/Cloud
Kind/Contenu
Kind/Data
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Front
Kind/IA
Kind/Infra
Kind/Monitoring
Kind/Security
Kind/Testing
Portée/Post-jury
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
ops/alerte
No milestone
No project
No assignees
1 participant
Notifications
Due date
Dependencies
No dependencies set
Reference
g2/enervision#92
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Exigence couverte
ENF-05, ENF-09, ENF-15
Épreuve servie
EC04 · Cloud et sécurisation
Charge estimée
1 j.h
Ce qu'on veut obtenir
Sortir une copie des sauvegardes du serveur, et remettre en marche l'outillage d'administration que le durcissement SSH vient de couper.
Les sauvegardes tournent, c'est vérifié : vidage de la forge à 12h30 (11 Mo aujourd'hui), vidage PostgreSQL à 2h30, rétention de sept jours. Mais tout reste sur la machine. Une perte du conteneur LXC emporte le dépôt, les tickets, les bases et leurs sauvegardes d'un seul coup.
Critères d'acceptation
root. Critère amendé le 3 septembre : il disait « par le comptedeploy» ; le motif du changement est en commentaire ci-dessous. Le périmètre réel était de huit scripts, pas trois.rootqui n'existe plus.Comment on le vérifie
Commande la copie hors serveur listée depuis le poste, puis unzip -l sur l'archive de la forge
Attendu une archive datée du jour, contenant gitea-db.sql et gitea-repo/
Preuve la sortie du listing et le chronomètre de la restauration
Manuel d'exploitation à mettre à jour
docs/runbooks/forge.md, section sauvegarde, etdocs/FORGE.mdpour l'accèsRisque et retour arrière
Une copie qui part vers un poste de l'équipe déplace le risque plutôt que de le supprimer : deux machines dans la même salle tombent ensemble. Le stockage de secours cloud du #69 est la vraie réponse, ce ticket peut se contenter d'une copie locale en attendant, à condition de le dire.
Deux critères sur cinq sont tenus, demande de fusion ci-dessus.
La copie hors serveur existe et tourne. Planifiée à 18h30 du lundi au vendredi vers
~/eadl/sauvegardes/, rétention de quatorze jours. Première exécution faite : 14 Mo, archive du jour vérifiée.Elle est vérifiée, pas seulement comptée. Et la vérification a servi immédiatement : le manuel annonçait
gitea-db.sqletgitea-repo/, noms hérités de l'ancêtre du projet. Forgejo 12 écritforgejo-db.sqletrepos/. Quelqu'un qui aurait suivi le manuel pour contrôler une sauvegarde l'aurait crue vide alors qu'elle contient 2 406 fichiers.Restent trois choses : la restauration jouée chronomètre en main, le recâblage des scripts d'administration qui passaient par
root, et le raccordement au stockage de secours du #69 quand il existera. Les deux machines sont dans la même salle : cette copie réduit le risque, elle ne le supprime pas.Restauration jouée ce soir depuis la copie hors serveur, sur machine vierge (mon poste, hors salle). Chronométrée : 9 min 51 s, pour une cible de 4 heures.
Périmètre restauré et vérifié :
healthz: pass, 2 dépôts, 75 tickets, les 7 comptes (forgejo admin user list). Détail utile : le vidage contientforgejo.dbprêt à l'emploi, ne pas rejouerforgejo-db.sqlpar-dessus.shared_preload_libraries=timescaledbobligatoire, sinonpg_restoreéchoue. Les bases sont quasi vides à ce stade — l'exercice sera à rejouer quand la collecte produira. Procédure et frictions consignées dansdocs/runbooks/reprise.md(MR #99).Chrono : départ 21:31:10 (début du rapatriement de la copie), arrivée 21:41:01 (forge et base interrogées sur la machine de secours).
Reste un critère : le recâblage des scripts du poste (
sync-cles.sh,qui.sh,50-backup.sh) sur le comptedeploy— demain en salle, les scripts vivent sur le poste.Critère 4 fait, et il était plus large que ce que le ticket disait
Le ticket nommait trois scripts. Il y en avait huit qui se connectaient encore en
root@, et ils étaient tous cassés : le durcissement du 1er septembre a retiré rootd'
AllowUsers, doncssh root@10.105.200.41rendPermission denieddepuis deux jours.Personne ne s'en était aperçu parce que personne ne les avait relancés.
Tous passent désormais par
ADMIN_USER, nominatif, avec une élévationsudoexplicitesur la charge distante.
Pourquoi un compte nominatif et non
deployLe critère disait « par le compte
deploy». Je m'en écarte, pour deux raisons.La première est de fond.
deployest l'identité de la chaîne de déploiement, cellequ'Ansible et le déploiement continu empruntent. Faire passer l'outillage humain par elle
mettrait chaque geste manuel sous un nom qui signifie « la chaîne l'a fait ». C'est
exactement ce que le passage aux comptes nominatifs a permis de distinguer, et ce que
qui.shsert à lire.La seconde est matérielle.
/opt/g2-forgeest en0750 root:root:deployne peutmême pas le traverser.
50-backup.shaurait échoué au premiercd.Deux scripts n'étaient pas à recâbler, ils étaient obsolètes
sync-cles.shetrevoquer-cles-provisoires.shécrivaient dans/root/.ssh/authorized_keys, fichier qui ne sert plus à rien depuis que chacun a soncompte. Ils ne cassaient rien : ils ne faisaient plus rien du tout. Réécrits pour poser et
retirer les clés dans le compte de chacun.
revoquer-cles-provisoires.shgagne au passage un garde-fou : il refuse de retirer la cléprovisoire d'un membre dont aucune clé personnelle n'est connue. Sans lui, il coupait la
personne du serveur.
Un défaut trouvé dans ma propre réécriture, avant de la lancer
Ma première version de
sync-cles.shne poussait que les clés personnelles et retiraitla clé d'automatisation du compte d'administration. Or les huit scripts s'y connectent
avec elle : elle aurait coupé tout l'outillage d'un coup, sans que rien ne le dise avant
le lancement suivant. C'est la famille de panne du 3 septembre. La clé est de nouveau
posée en tête, et le commentaire dit pourquoi.
Vérifications réelles
qui.sh, joué sur le serveur :Il révèle au passage que je me connecte encore avec ma clé provisoire, pas une clé
personnelle. Son découpage a dû être repris : il reposait sur une expression régulière
calée sur la date en anglais, alors que le serveur journalise en français. Elle ne
reconnaissait aucune ligne, en silence.
50-backup.sh, joué sur le serveur :Son
scplisait un chemin que seul root peut traverser, échec avalé par un2>/dev/null.Le vidage passe maintenant par un relais dans
/tmp, appartenant au compte, suppriméaprès rapatriement. Et l'échec est désormais bruyant.
Ce qui reste
sync-cles.shetrevoquer-cles-provisoires.shsont réécrits mais pas joués. Ilsréécrivent l'accès des six personnes ; ça se lance délibérément, pas au fil d'une
correction.
approuvée par Florian et Gabriel, chaîne au vert, sans conflit.
Point du 4 septembre, après vérification sur le serveur et sur le poste. Deux
critères passent, un revient en arrière.
Critère 3, la restauration : fait
Jouée le 3 septembre depuis la copie hors serveur, sur machine vierge, en
9 min 51 s pour une cible de quatre heures. La preuve est dans le
commentaire du 3 septembre, elle n'avait simplement pas été cochée.
Critère 5, le manuel : fait
Plus aucune occurrence de
root@dansdocs/.forge.mddécritssh <prénom>@10.105.200.41avecsudosans mot de passe.Critère 1, la copie quotidienne : décoché, il était faux
La planification existait,
30 18 * * 1-5, mais elle n'a jamais tourné.Aucun
journal.logn'a jamais été écrit dans~/eadl/sauvegardes/. Ce n'est pascron : le miroir, planifié à midi et à 18 h, a bien tourné à midi le 3 et pas à
18 h. Le poste est éteint à cette heure là.
Les trois copies existantes, des 2, 3 et 4 septembre, sont donc toutes manuelles.
Une sauvegarde qui dépend d'une machine allumée se planifie quand la machine est
allumée.
Corrigé : la ligne passe à
45 12 * * 1-5. Après le vidage de la forge de12 h 30, pas avant, sans quoi la copie emporterait systématiquement l'archive de
la veille. Le critère se recochera quand un
journal.logexistera, c'est-à-direaujourd'hui à 12 h 45.
Et un trou qui n'était dans aucun critère : MinIO
Le stockage objet n'était sauvegardé nulle part. Ni la tâche PostgreSQL de
2 h 30 ni celle de la forge de 12 h 30 ne le touchent, et l'archive rapatriée ne
couvrait que
/opt/g2-forge/backupset/var/backups/postgresql.Toute la zone médaillon, 79 Mo et 9851 objets, tenait sur un seul disque sans
copie. Et ce n'est pas rattrapable : l'API bouchon ne rend pas d'historique au
delà de sa fenêtre.
stockage-minio.mdproposait bien unmc mirror, mais vers/srv/enervision/sauvegardes, le même disque que MinIO. Ça protège d'unefausse manoeuvre, pas de la perte de la machine.
Traité par la #146, éprouvée dans les trois cas contre le vrai serveur :
L'archive passe de 49 à 52 Mo seulement, le JSON de bronze se comprimant bien.
Ce qui reste
Le critère 1, jusqu'à 12 h 45 aujourd'hui. Et la fusion de la #146, actuellement
bloquée par une panne du point d'audit npm qui n'a rien à voir avec ce ticket.
Critère 1 atteint, les cinq sont cochés.
La copie planifiée a tourné seule aujourd'hui à 12 h 45, pour la première
fois.
~/eadl/sauvegardes/journal.logexiste et porte sa sortie, l'archive dujour est datée de 12 h 45, et le script l'a vérifiée.
Rappel de ce qui bloquait : la ligne était planifiée à
30 18 * * 1-5et n'avaitjamais tourné, le poste étant éteint à cette heure là. Ce n'était pas cron :
le miroir, planifié à midi et à 18 h, tournait bien à midi et jamais à 18 h. La
ligne est passée à
45 12 * * 1-5, après le vidage de la forge de 12 h 30 et nonavant, sans quoi la copie emporterait systématiquement l'archive de la veille.
Le stockage objet est dedans
La #146 étant fusionnée, le script du poste a été resynchronisé depuis le dépôt.
Éprouvé à l'instant :
L'archive passe de 52 à 129 Mo dans la journée : la zone bronze a grossi, et la
zone argent y est maintenant, la transformation tournant toutes les heures depuis
le #136.
Un point d'exploitation à connaître : le script du poste est une copie, pas
un lien vers le dépôt. Une fusion qui le modifie ne met pas la machine à jour. Un
cpdepuisinfra/scripts/reste nécessaire, et c'est le #64.Ce que ça ne résout toujours pas
Les deux machines sont dans la même salle et tombent ensemble. C'est un filet,
pas une sauvegarde hors site. La vraie réponse reste le stockage de secours du
#69.