Aller au contenu
Sécurité medium

NixOS : rollback, générations et mode rescue

17 min de lecture

NixOS ne peut pas être cassé de façon irréversible. Chaque nixos-rebuild switch crée une génération — un instantané complet du système que vous pouvez réactiver en une commande ou depuis le boot loader. Si le système ne démarre plus du tout, l’ISO d’installation et nixos-enter permettent de réparer sans réinstaller. Ce guide vous fait pratiquer les trois niveaux de récupération, du plus simple au plus radical, puis vous montre comment nettoyer les générations devenues inutiles.

  • Diagnostiquer un échec de nixos-rebuild et comprendre le message d’erreur
  • Revenir en arrière avec nixos-rebuild switch --rollback
  • Choisir une génération dans le menu systemd-boot au démarrage
  • Réparer un système non bootable depuis l’ISO avec nixos-enter
  • Nettoyer les anciennes générations avec nix-collect-garbage -d
  • Optimiser l’espace disque avec nix store optimise

Ce lab correspond au moment où vous commencez à modifier votre configuration NixOS avec confiance — et où une erreur finit par arriver.

  • Vous avez ajouté une option qui n’existe pas et nixos-rebuild échoue
  • Vous avez changé le port SSH ou supprimé un service par erreur et le système fonctionne mal
  • Après un nixos-rebuild switch, un service critique ne démarre plus et vous devez revenir en arrière rapidement
  • Votre VM NixOS a accumulé des dizaines de générations et le disque se remplit
  • Dans le pire des cas, le système ne boot plus et vous devez intervenir depuis l’ISO
  • Lab 8 terminé (configuration NixOS maîtrisée, modules en place)
  • Familiarité avec les générations et le store Nix
  • L’ISO NixOS minimal disponible (celle utilisée pour le Lab 1)

Chaque appel à nixos-rebuild switch produit une nouvelle génération dans le profil système :

Fenêtre de terminal
sudo nix-env --list-generations --profile /nix/var/nix/profiles/system
1 2026-04-14 10:47:12
2 2026-04-14 11:09:05
3 2026-04-14 19:19:57
4 2026-04-14 19:21:14 (current)

Chaque génération est un lien symbolique vers un chemin immutable dans /nix/store/. La génération courante est aussi pointée par /run/current-system :

Fenêtre de terminal
readlink /run/current-system
/nix/store/2fiz4aj5j38fi59ry379np9gx3zagmib-nixos-system-nixos-lab-25.11.20260413.7e495b7

Le boot loader (ici systemd-boot) maintient une entrée par génération dans /boot/loader/entries/. Au démarrage, vous pouvez choisir n’importe laquelle.

Avant de revenir en arrière, identifiez ce qui a changé entre deux générations :

Fenêtre de terminal
sudo nix profile diff-closures --profile /nix/var/nix/profiles/system
Version 2 -> 3:
fail2ban: ∅ → 1.1.0, +5144.9 KiB
python3.13-pyinotify: ∅ → 0.9.6, +296.0 KiB
python3.13-systemd-python: ∅ → 235, +403.1 KiB
Version 3 -> 4:
NetworkManager: ∅ → ..., +X KiB
dnsmasq: ∅ → 2.91, +623.2 KiB

Chaque transition montre les paquets ajoutés (∅ → version), supprimés (version → ∅) et mis à jour. C’est l’équivalent d’un git diff appliqué à votre système.

Le cas le plus fréquent : vous avez introduit une option invalide dans votre configuration.

  1. Introduire une erreur volontaire

    Ajoutez une option SSH qui n’existe pas dans network.nix :

    services.openssh.settings.ThisOptionDoesNotExist = true;
  2. Tenter le rebuild

    Fenêtre de terminal
    cd /etc/nixos
    sudo nixos-rebuild switch --flake .#nixos-lab

    Le rebuild échoue avec un message explicite :

    error: Cannot build '...check-sshd-config.drv'.
    Last 2 log lines:
    > sshd.conf-final: line 12: Bad configuration option: ThisOptionDoesNotExist
    > sshd.conf-final: terminating, 1 bad configuration options
  3. Vérifier que le système est intact

    Fenêtre de terminal
    sudo nix-env --list-generations --profile /nix/var/nix/profiles/system

    Aucune nouvelle génération n’a été créée. Le système tourne toujours sur la génération précédente — rien n’a changé.

  4. Corriger et reconstruire

    Retirez l’option invalide de network.nix, puis relancez le rebuild.

Scénario 2 — Rollback après un changement regretté

Section intitulée « Scénario 2 — Rollback après un changement regretté »

Le rebuild a réussi, mais le changement pose problème : vous avez changé le port SSH, supprimé fail2ban, ou un service ne fonctionne plus comme prévu.

  1. Appliquer un changement fonctionnel mais indésirable

    Modifiez network.nix pour changer le port SSH et supprimer fail2ban :

    networking.firewall.allowedTCPPorts = [ 2222 ];
    services.openssh.ports = [ 2222 ];
    # fail2ban supprimé

    Appliquez :

    Fenêtre de terminal
    cd /etc/nixos
    sudo nixos-rebuild switch --flake .#nixos-lab

    Le rebuild réussit — une nouvelle génération est créée. SSH écoute maintenant sur le port 2222 et fail2ban est arrêté.

  2. Revenir en arrière immédiatement

    Fenêtre de terminal
    sudo nixos-rebuild switch --rollback
    switching profile from version 5 to 4
    activating the configuration...
    restarting the following units: sshd.service
    the following new units were started: fail2ban.service
  3. Vérifier le retour à l’état précédent

    Fenêtre de terminal
    # SSH revenu sur le port 22
    ss -tlnp | grep 22
    # fail2ban réactivé
    systemctl is-active fail2ban

Le rollback réactive l’ancienne génération à chaud : les services sont redémarrés, les ports changent, les paquets redeviennent disponibles — sans reboot.

Si le système a redémarré sur une génération cassée (un service critique empêche le login, par exemple), vous ne pouvez plus utiliser SSH. Le boot loader permet de choisir une autre génération avant que le système ne démarre.

  1. Préparer le rollback au prochain démarrage

    Si vous avez encore accès au système (via la console KVM par exemple) :

    Fenêtre de terminal
    sudo nixos-rebuild boot --rollback

    Cette commande ne touche pas le système en cours d’exécution. Elle configure le boot loader pour démarrer sur la génération précédente au prochain reboot.

    switching profile from version 5 to 4
    Done. The new configuration is /nix/var/nix/profiles/system
  2. Redémarrer

    Fenêtre de terminal
    sudo reboot

    Au prochain démarrage, systemd-boot charge la génération 4 — avec SSH sur le port 22 et fail2ban actif.

  3. Alternative : sélection manuelle dans le menu

    Si vous n’avez plus accès au système du tout, ouvrez la console graphique de la VM (via virt-manager ou virsh console) et :

    • Au démarrage, le menu systemd-boot s’affiche pendant 5 secondes
    • Utilisez les flèches pour sélectionner une ancienne génération (ex : Generation 4)
    • Appuyez sur Entrée

    Le système démarre sur la génération choisie. Elle reste active jusqu’au prochain nixos-rebuild switch.

Fenêtre de terminal
sudo ls /boot/loader/entries/
nixos-generation-1.conf
nixos-generation-2.conf
nixos-generation-3.conf
nixos-generation-4.conf
nixos-generation-5.conf

Chaque fichier correspond à une génération. Le fichier loader.conf indique laquelle est chargée par défaut :

Fenêtre de terminal
sudo cat /boot/loader/loader.conf
timeout 5
default nixos-generation-4.conf
console-mode keep

Scénario 4 — Réparer depuis l’ISO avec nixos-enter

Section intitulée « Scénario 4 — Réparer depuis l’ISO avec nixos-enter »

Quand aucune génération ne permet de démarrer (store corrompu, partition abîmée, mauvaise configuration du boot loader), la dernière option est de booter depuis l’ISO d’installation et d’utiliser nixos-enter pour accéder au système installé.

  1. Attacher l’ISO à la VM

    Depuis l’hôte KVM :

    Fenêtre de terminal
    virsh change-media nixos-lab sda \
    /chemin/vers/nixos-minimal-25.11-x86_64-linux.iso --insert

    Puis modifiez l’ordre de boot pour démarrer sur le CD-ROM (via virt-manager → Vue → Détails → Options de démarrage, ou via virsh edit).

  2. Démarrer sur l’ISO et monter les partitions

    Une fois dans le shell de l’ISO live :

    Fenêtre de terminal
    # Identifier les partitions
    lsblk -f
    # Monter la racine
    mount /dev/vda2 /mnt
    # Monter la partition EFI
    mount /dev/vda1 /mnt/boot
  3. Entrer dans le système installé

    Fenêtre de terminal
    nixos-enter

    Vous êtes maintenant dans un chroot complet du système installé, avec accès à tous les fichiers de configuration et au store Nix.

  4. Corriger la configuration et reconstruire

    Fenêtre de terminal
    cd /etc/nixos
    # Corriger le fichier fautif (vim, nano...)
    vim network.nix
    # Reconstruire
    nixos-rebuild switch --flake .#nixos-lab
  5. Quitter et redémarrer

    Fenêtre de terminal
    exit # quitter nixos-enter
    umount /mnt/boot
    umount /mnt
    reboot

    Retirez l’ISO du lecteur CD et démarrez normalement. Le système utilise la configuration corrigée.

Chaque génération conserve ses paquets dans le store. Après plusieurs modifications, l’espace disque peut grossir. Le garbage collector supprime tout ce qui n’est plus référencé par aucune génération active.

  1. Mesurer l’espace avant nettoyage

    Fenêtre de terminal
    df -h /
    du -sh /nix/store
    sudo nix-env --list-generations --profile /nix/var/nix/profiles/system

    Exemple de sortie :

    /dev/vda2 20G 2.9G 16G 16% /
    2.8G /nix/store
    1 2026-04-14 10:47:12
    2 2026-04-14 11:09:05
    3 2026-04-14 19:19:57
    4 2026-04-14 19:21:14 (current)
    5 2026-04-15 07:21:39
  2. Supprimer toutes les anciennes générations et lancer le GC

    Fenêtre de terminal
    sudo nix-collect-garbage -d

    L’option -d (delete) supprime d’abord toutes les générations sauf la courante, puis lance le ramasse-miettes sur le store.

  3. Vérifier le résultat

    Fenêtre de terminal
    df -h /
    du -sh /nix/store
    sudo nix-env --list-generations --profile /nix/var/nix/profiles/system
    /dev/vda2 20G 2.3G 16G 13% /
    2.3G /nix/store
    4 2026-04-14 19:21:14 (current)

    Seule la génération courante subsiste. Le store est passé de 2.8 Go à 2.3 Go.

  4. Nettoyer les entrées du boot loader

    Le garbage collector ne touche pas les entrées de systemd-boot. Pour les synchroniser, lancez un rebuild :

    Fenêtre de terminal
    cd /etc/nixos
    sudo nixos-rebuild boot --flake .#nixos-lab

    Vérifiez qu’il ne reste qu’une seule entrée :

    Fenêtre de terminal
    sudo ls /boot/loader/entries/
    nixos-generation-4.conf

Même après le GC, le store peut contenir des fichiers identiques copiés dans différents paquets. La commande nix store optimise les remplace par des hard links :

Fenêtre de terminal
sudo nix store optimise
237.87 MiB freed by hard-linking 63603 files

Dans notre cas, cela a réduit le store de 2.3 Go à 2.2 Go — un gain supplémentaire de 238 Mo.

Pour ne plus y penser, activez le garbage collector automatique dans configuration.nix :

nix.gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 30d";
};

Cette configuration supprime chaque semaine les générations de plus de 30 jours, puis lance le GC. Adaptez la durée selon vos besoins — sur un serveur de production, garder au moins 2 à 4 semaines de générations est recommandé.

SituationCommandeEffet
Rebuild échouéRien à faireLe système reste sur la génération courante
Changement regrettésudo nixos-rebuild switch --rollbackRéactive la génération précédente à chaud
Préparer un rollback au rebootsudo nixos-rebuild boot --rollbackConfigure le boot loader sans toucher au système actif
Système non bootableMenu systemd-boot → ancienne générationDémarre sur une génération fonctionnelle
Rien ne bootISO + mount + nixos-enterChroot dans le système installé pour corriger
Lister les générationssudo nix-env --list-generations -p /nix/var/nix/profiles/systemVoir l’historique complet
Comparer les générationssudo nix profile diff-closures --profile /nix/var/nix/profiles/systemDiff des paquets entre chaque génération
Nettoyersudo nix-collect-garbage -dSupprime anciennes générations + GC du store
Optimisersudo nix store optimiseDéduplique les fichiers par hard links
  1. Le rebuild échoué ne crée pas de génération

    Introduisez une option invalide, lancez nixos-rebuild switch, vérifiez que le nombre de générations n’a pas changé.

  2. Le rollback restaure les services

    Après un nixos-rebuild switch --rollback, vérifiez que les services supprimés sont revenus (systemctl is-active fail2ban) et que les ports sont corrects (ss -tlnp).

  3. Le boot loader reflète les générations

    Vérifiez que ls /boot/loader/entries/ contient une entrée par génération et que loader.conf pointe vers la génération courante.

  4. Le GC libère de l’espace

    Comparez du -sh /nix/store et df -h / avant et après nix-collect-garbage -d.

  5. nix store optimise gagne de l’espace supplémentaire

    Lancez la commande et vérifiez le nombre de Mo libérés par la déduplication.

Vous êtes probablement déjà sur la première génération. Vérifiez avec :

Fenêtre de terminal
sudo nix-env --list-generations --profile /nix/var/nix/profiles/system

S’il n’y a qu’une seule génération, il n’y a rien vers quoi revenir.

Les anciennes entrées de boot restent après le GC

Section intitulée « Les anciennes entrées de boot restent après le GC »

Le garbage collector ne synchronise pas les entrées de systemd-boot. Exécutez un nixos-rebuild boot pour les nettoyer.

Vérifiez que les partitions sont montées dans le bon ordre : la racine (/) sur /mnt en premier, puis /boot sur /mnt/boot. Si la partition racine utilise un système de fichiers chiffré (LUKS), déchiffrez-la d’abord avec cryptsetup open.

Les cas de corruption du store sont très rares (matériel défaillant). Vous pouvez tenter une vérification :

Fenêtre de terminal
sudo nix store verify --all

Si des chemins sont endommagés, nix store repair peut les reconstruire à partir des sources si elles sont encore disponibles. En dernier recours, une réinstallation depuis l’ISO en conservant /home est la solution.

Le timeout par défaut est de 5 secondes. Si le menu disparaît trop vite, maintenez la touche Espace enfoncée au démarrage. Vous pouvez aussi augmenter le timeout :

boot.loader.timeout = 10;
  • Un rebuild échoué ne touche pas au système — la compilation protège avant l’activation
  • nixos-rebuild switch --rollback réactive la génération précédente instantanément, sans reboot
  • nixos-rebuild boot --rollback prépare le rollback pour le prochain démarrage
  • Le menu systemd-boot permet de choisir n’importe quelle génération au démarrage
  • L’ISO + nixos-enter est le filet de sécurité ultime quand plus rien ne boot
  • Versionnez /etc/nixos avec git — le rollback système ne restaure pas vos fichiers de configuration
  • nix-collect-garbage -d supprime les anciennes générations — ne le faites que si la génération courante est stable
  • nix store optimise économise de l’espace supplémentaire par déduplication

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn