<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>#systemd — Blog d'Ange Bonkoski</title><link>https://journal.ange-bonkoski.fr/tags/systemd/</link><description>Journal de mon homelab et write-ups de labs de cybersécurité.</description><language>fr</language><copyright>Ange Bonkoski, licence CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/deed.fr)</copyright><lastBuildDate>Sun, 18 Oct 2026 11:00:00 +0200</lastBuildDate><atom:link href="https://journal.ange-bonkoski.fr/tags/systemd/index.xml" rel="self" type="application/rss+xml"/><item><title>La sauvegarde qui s'est évaporée</title><link>https://journal.ange-bonkoski.fr/journal/la-sauvegarde-qui-sest-evaporee/</link><pubDate>Sun, 18 Oct 2026 11:00:00 +0200</pubDate><guid>https://journal.ange-bonkoski.fr/journal/la-sauvegarde-qui-sest-evaporee/</guid><category>homelab</category><category>sauvegarde</category><category>systemd</category><category>zimaos</category><category>supervision</category><description>&lt;p&gt;Le 9 octobre, en cherchant où ajouter une nouvelle tâche planifiée sur mon&#10;serveur, j&amp;rsquo;ai tapé &lt;code&gt;crontab -l&lt;/code&gt;. La réponse était vide. Ma sauvegarde&#10;nocturne, celle qui protège mon coffre de mots de passe, n&amp;rsquo;existait plus.&lt;/p&gt;&#10;&lt;p&gt;Elle ne s&amp;rsquo;était pas lancée la nuit précédente. Et aucune de mes alertes&#10;n&amp;rsquo;avait sonné.&lt;/p&gt;&#10;&lt;h2 id="le-dispositif-de-sauvegarde"&gt;Le dispositif de sauvegarde&lt;/h2&gt;&#10;&lt;p&gt;Chaque nuit à 3 h 30, un script sauvegarde les données importantes du&#10;serveur avec &lt;strong&gt;restic&lt;/strong&gt;, un outil qui produit des sauvegardes chiffrées,&#10;dédupliquées et versionnées. Le script :&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;fait une copie cohérente de la base de données du coffre, sans&#10;l&amp;rsquo;arrêter ;&lt;/li&gt;&#10;&lt;li&gt;l&amp;rsquo;envoie dans le dépôt restic, sur un disque séparé ;&lt;/li&gt;&#10;&lt;li&gt;supprime les anciennes versions selon une règle de rétention ;&lt;/li&gt;&#10;&lt;li&gt;vérifie un échantillon des données ;&lt;/li&gt;&#10;&lt;li&gt;signale « tout va bien » à ma supervision (Uptime Kuma), &lt;strong&gt;seulement si&#10;toutes les étapes ont réussi&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;Uptime Kuma attend ce signal. S&amp;rsquo;il ne reçoit rien pendant 26 heures, il&#10;m&amp;rsquo;envoie une alerte sur Discord. Sur le papier, une sauvegarde manquée ne&#10;pouvait donc pas passer inaperçue.&lt;/p&gt;&#10;&lt;h2 id="la-chronologie"&gt;La chronologie&lt;/h2&gt;&#10;&#10;&lt;div class="tableau" role="region" aria-label="Tableau" tabindex="0"&gt;&#10;&lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th class="aligne-left"&gt;Moment&lt;/th&gt;&#10; &lt;th class="aligne-left"&gt;Ce qui s&amp;rsquo;est passé&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td class="aligne-left"&gt;8 oct., 3 h 30&lt;/td&gt;&#10; &lt;td class="aligne-left"&gt;Dernière sauvegarde réussie.&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td class="aligne-left"&gt;8 oct., 17 h 40&lt;/td&gt;&#10; &lt;td class="aligne-left"&gt;Je redémarre le serveur pour valider un changement de configuration SSH, sans aucun rapport avec les sauvegardes.&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td class="aligne-left"&gt;9 oct., 3 h 30&lt;/td&gt;&#10; &lt;td class="aligne-left"&gt;Aucune sauvegarde. Aucun message.&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td class="aligne-left"&gt;9 oct., après-midi&lt;/td&gt;&#10; &lt;td class="aligne-left"&gt;Plusieurs redémarrages pour d&amp;rsquo;autres travaux. Uptime Kuma affiche toujours « en ligne ».&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td class="aligne-left"&gt;9 oct., 17 h 40&lt;/td&gt;&#10; &lt;td class="aligne-left"&gt;Je découvre par hasard que la tâche planifiée a disparu.&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;h2 id="première-énigme--où-est-passée-la-tâche-"&gt;Première énigme : où est passée la tâche ?&lt;/h2&gt;&#10;&lt;p&gt;Mon serveur tourne sous &lt;strong&gt;ZimaOS&lt;/strong&gt;, un système conçu pour faire tourner des&#10;conteneurs. Pour être robuste, il ne ressemble pas à une distribution&#10;Linux classique :&lt;/p&gt;&#10;&#10;&lt;div class="tableau" role="region" aria-label="Tableau" tabindex="0"&gt;&#10;&lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th class="aligne-left"&gt;Zone&lt;/th&gt;&#10; &lt;th class="aligne-left"&gt;Comportement&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td class="aligne-left"&gt;&lt;code&gt;/&lt;/code&gt; (le système)&lt;/td&gt;&#10; &lt;td class="aligne-left"&gt;en lecture seule&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td class="aligne-left"&gt;&lt;code&gt;/etc&lt;/code&gt; (la configuration)&lt;/td&gt;&#10; &lt;td class="aligne-left"&gt;modifiable et conservée&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td class="aligne-left"&gt;&lt;code&gt;/var&lt;/code&gt;&lt;/td&gt;&#10; &lt;td class="aligne-left"&gt;&lt;strong&gt;en mémoire vive (tmpfs) : vidée à chaque démarrage&lt;/strong&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td class="aligne-left"&gt;la partition de données&lt;/td&gt;&#10; &lt;td class="aligne-left"&gt;modifiable et conservée&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;Or, quand on crée une tâche avec &lt;code&gt;crontab -e&lt;/code&gt;, cron l&amp;rsquo;enregistre dans&#10;&lt;code&gt;/var/spool/cron/&lt;/code&gt;. Sur ZimaOS, ma tâche vivait donc dans la mémoire vive.&#10;Elle a fonctionné parfaitement &lt;strong&gt;jusqu&amp;rsquo;au premier redémarrage&lt;/strong&gt;, qui l&amp;rsquo;a&#10;effacée sans un bruit.&lt;/p&gt;&#10;&#10;&#10;&#10;&#10;&#10;&#10;&#10;&lt;div class="encadre encadre-attention" role="note"&gt;&#10; &lt;p class="encadre-titre"&gt;&#10; &#10; &#10; &lt;svg aria-hidden="true" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z"/&gt;&lt;path d="M12 9v4"/&gt;&lt;path d="M12 17h.01"/&gt;&lt;/svg&gt;&#10; &#10; &lt;span&gt;Attention&lt;/span&gt;&#10; &lt;/p&gt;&#10; &#10; &lt;div class="encadre-contenu"&gt;&#10; &lt;p&gt;Sur un système dont &lt;code&gt;/var&lt;/code&gt; est en tmpfs, &lt;code&gt;crontab -e&lt;/code&gt; semble fonctionner :&#10;la tâche s&amp;rsquo;affiche, elle se lance, tout a l&amp;rsquo;air normal. Le problème&#10;n&amp;rsquo;apparaît qu&amp;rsquo;au redémarrage suivant, parfois des semaines plus tard.&lt;/p&gt;&#10;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&#10;&lt;h2 id="deuxième-énigme--pourquoi-aucune-alerte-"&gt;Deuxième énigme : pourquoi aucune alerte ?&lt;/h2&gt;&#10;&lt;p&gt;C&amp;rsquo;est la question qui m&amp;rsquo;a le plus appris. Deux défauts se sont cumulés.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Un script qui ne se lance pas ne peut rien signaler.&lt;/strong&gt; Mon script envoie&#10;« échec » quand une étape échoue. Mais là, il n&amp;rsquo;a jamais démarré. Il ne&#10;restait que le délai de 26 heures pour me prévenir.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Le chien de garde redémarrait avec ce qu&amp;rsquo;il surveillait.&lt;/strong&gt; Uptime Kuma&#10;tourne sur le même serveur. À chaque redémarrage de l&amp;rsquo;après-midi, son&#10;compte à rebours de 26 heures repartait de zéro. Il aurait fini par&#10;m&amp;rsquo;alerter… si j&amp;rsquo;avais arrêté de redémarrer.&lt;/p&gt;&#10;&#10;&#10;&#10;&#10;&#10;&#10;&#10;&lt;div class="encadre encadre-lecon" role="note"&gt;&#10; &lt;p class="encadre-titre"&gt;&#10; &#10; &#10; &lt;svg aria-hidden="true" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M9 18h6"/&gt;&lt;path d="M10 22h4"/&gt;&lt;path d="M12 2a7 7 0 0 0-4 12.7c.6.5 1 1.3 1 2.1V17h6v-.2c0-.8.4-1.6 1-2.1A7 7 0 0 0 12 2z"/&gt;&lt;/svg&gt;&#10; &#10; &lt;span&gt;Leçon&lt;/span&gt;&#10; &lt;/p&gt;&#10; &#10; &lt;div class="encadre-contenu"&gt;&#10; &lt;p&gt;Un chien de garde doit vivre ailleurs que ce qu&amp;rsquo;il garde. Quand le&#10;serveur tombe, la supervision qui tourne dessus tombe avec lui.&lt;/p&gt;&#10;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&#10;&lt;h2 id="la-correction--un-timer-systemd"&gt;La correction : un timer systemd&lt;/h2&gt;&#10;&lt;p&gt;Puisque &lt;code&gt;/etc&lt;/code&gt; est conservé, la tâche doit être déclarée là. J&amp;rsquo;ai remplacé&#10;la ligne cron par un &lt;strong&gt;timer systemd&lt;/strong&gt; : un couple de deux petits fichiers.&lt;/p&gt;&#10;&lt;p&gt;Le service dit &lt;strong&gt;quoi&lt;/strong&gt; lancer :&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# /etc/systemd/system/sauvegarde.service&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Sauvegarde restic nocturne&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Service]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;oneshot&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/chemin/vers/sauvegarde.sh&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Le timer dit &lt;strong&gt;quand&lt;/strong&gt; le lancer :&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# /etc/systemd/system/sauvegarde.timer&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Lance la sauvegarde chaque nuit à 3 h 30&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Timer]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;OnCalendar&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;*-*-* 03:30:00&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Persistent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Install]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;timers.target&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La ligne &lt;code&gt;Persistent=true&lt;/code&gt; est le vrai gain par rapport à cron : si le&#10;serveur était éteint à 3 h 30, la sauvegarde est lancée dès le démarrage&#10;suivant au lieu d&amp;rsquo;être simplement sautée.&lt;/p&gt;&#10;&lt;p&gt;On active le timer, puis on vérifie la date du prochain lancement :&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl daemon-reload&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now sauvegarde.timer&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl list-timers sauvegarde.timer&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Je n&amp;rsquo;ai pas considéré le problème réglé avant de l&amp;rsquo;avoir &lt;strong&gt;prouvé&lt;/strong&gt; : un&#10;redémarrage, puis &lt;code&gt;systemctl list-timers&lt;/code&gt; à nouveau. Le timer était&#10;toujours là.&lt;/p&gt;&#10;&lt;h2 id="lerreur-pendant-la-correction"&gt;L&amp;rsquo;erreur pendant la correction&lt;/h2&gt;&#10;&lt;p&gt;J&amp;rsquo;ai aussi fait une erreur en corrigeant. J&amp;rsquo;ai deux scripts aux noms&#10;proches : celui qui fait la sauvegarde complète, et un petit outil qui&#10;transmet ses arguments à restic. Mon premier service lançait… le second.&#10;Résultat : le journal ne contenait que l&amp;rsquo;aide de restic.&lt;/p&gt;&#10;&lt;p&gt;Depuis, ma documentation distingue clairement les deux, avec une phrase&#10;pour chacun : ce qu&amp;rsquo;il fait, et quand on l&amp;rsquo;utilise.&lt;/p&gt;&#10;&lt;h2 id="ce-que-jen-retiens"&gt;Ce que j&amp;rsquo;en retiens&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Un changement peut casser quelque chose qui n&amp;rsquo;a rien à voir avec&#10;lui.&lt;/strong&gt; J&amp;rsquo;avais redémarré pour tester SSH, pas les sauvegardes.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Connaître son système avant d&amp;rsquo;y appliquer ses habitudes.&lt;/strong&gt; &lt;code&gt;crontab -e&lt;/code&gt;&#10;est un bon réflexe sur une Debian, un piège sur ZimaOS.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Une absence de nouvelles n&amp;rsquo;est pas une bonne nouvelle.&lt;/strong&gt; Le silence&#10;peut vouloir dire « tout va bien » comme « rien ne s&amp;rsquo;est lancé ».&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Vérifier les tâches planifiées après chaque redémarrage&lt;/strong&gt;, au moins&#10;tant qu&amp;rsquo;on n&amp;rsquo;a pas prouvé qu&amp;rsquo;elles survivent.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Il me reste un chantier ouvert : déplacer ce chien de garde hors du&#10;serveur, pour qu&amp;rsquo;une panne complète déclenche enfin une alerte.&lt;/p&gt;&#10;</description></item></channel></rss>