NixOS décrit l’intégralité du système dans un fichier configuration.nix. Modifier ce fichier et lancer nixos-rebuild switch suffit pour ajouter un paquet, activer un service ou créer un utilisateur — sans toucher à un gestionnaire de paquets impératif. Ce guide vous montre comment explorer les options disponibles, modifier la configuration avec confiance, et factoriser le tout en modules lisibles. À la fin, votre VM dispose de fail2ban, d’un firewall, d’un second utilisateur et d’une configuration découpée en fichiers thématiques.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Explorer les options NixOS avec
nixos-optionet search.nixos.org - Ajouter et supprimer des paquets système (
environment.systemPackages) - Activer et configurer des services : fail2ban, firewall, OpenSSH
- Gérer les utilisateurs et les groupes déclarativement
- Factoriser la configuration en modules (
network.nix,users.nix) - Choisir entre
nixos-rebuild switch,testetbootselon le contexte - Lire le diff de génération avant d’appliquer un changement
Dans quel contexte ?
Section intitulée « Dans quel contexte ? »Ce lab correspond à la situation la plus courante sur NixOS : vous avez un système installé qui fonctionne, et vous voulez le faire évoluer.
- Vous venez d’installer NixOS (Lab 1 ou Lab 2) et vous voulez ajouter fail2ban pour protéger SSH
- Vous avez besoin d’un firewall qui n’autorise que le port 22
- Vous devez créer un second utilisateur pour un collègue ou un service
- Votre
configuration.nixgrossit et devient difficile à lire — il faut le découper en modules - Vous voulez comprendre la différence entre
switch,testetbootavant de toucher à un serveur
Prérequis
Section intitulée « Prérequis »- Lab 1 ou Lab 2 terminé (VM NixOS fonctionnelle avec une flake)
- Familiarité avec le langage Nix (attrsets, listes,
with) - Notion de modules et imports
Anatomie de configuration.nix
Section intitulée « Anatomie de configuration.nix »Le fichier configuration.nix est une fonction Nix qui reçoit un ensemble d’arguments et retourne un attribute set décrivant le système.
{ config, pkgs, modulesPath, ... }:{ # 1. Imports : modules supplémentaires imports = [ ... ];
# 2. Boot : chargeur de démarrage, modules noyau boot.loader.systemd-boot.enable = true;
# 3. Réseau : hostname, firewall, interfaces networking.hostName = "nixos-lab";
# 4. Services : SSH, fail2ban, etc. services.openssh.enable = true;
# 5. Utilisateurs users.users.lab = { ... };
# 6. Paquets système environment.systemPackages = with pkgs; [ vim git ];
# 7. Options Nix nix.settings.experimental-features = [ "nix-command" "flakes" ];
# 8. Version d'état system.stateVersion = "25.11";}Chaque ligne de ce fichier correspond à une option NixOS déclarée quelque part dans les modules de nixpkgs. Le système de modules fusionne automatiquement toutes les options de tous les fichiers importés.
Explorer les options disponibles
Section intitulée « Explorer les options disponibles »NixOS propose plus de 15 000 options documentées. Deux outils pour les découvrir :
nixos-option (en ligne de commande)
Section intitulée « nixos-option (en ligne de commande) »# Voir la valeur actuelle, le type et la description d'une optionnixos-option services.openssh.enableRésultat :
Value: true
Default: false
Type: boolean
Description: Whether to enable the OpenSSH secure shell daemon, which allows secure remote logins.Pour explorer les sous-options d’un service :
nixos-option services.fail2banThis attribute set contains:banactionbanaction-allportsbantimedaemonConfigdaemonSettingsenableextraPackagesextraSettingsignoreIPjailsmaxretrypackagepackageFirewallsearch.nixos.org (interface web)
Section intitulée « search.nixos.org (interface web) »Le site search.nixos.org/options propose une recherche full-text sur toutes les options NixOS. Tapez un mot-clé (ex : « fail2ban ») pour voir toutes les options associées, leur type, leur valeur par défaut et un lien vers le code source.
Ajouter et supprimer des paquets
Section intitulée « Ajouter et supprimer des paquets »Les paquets système se déclarent dans environment.systemPackages :
environment.systemPackages = with pkgs; [ vim git htop curl tmux];Pour ajouter un paquet, ajoutez-le à la liste. Pour le supprimer, retirez-le. Après chaque modification :
sudo nixos-rebuild switch --flake .#nixos-labLe paquet est installé ou supprimé immédiatement dans le profil système.
Rechercher un paquet
Section intitulée « Rechercher un paquet »nix search nixpkgs fail2banCette commande interroge le cache nixpkgs pour trouver les paquets correspondants.
Activer et configurer un service
Section intitulée « Activer et configurer un service »Activer fail2ban
Section intitulée « Activer fail2ban »fail2ban surveille les logs d’authentification et bannit les IP qui échouent trop de fois. Sur NixOS, une seule section suffit :
services.fail2ban = { enable = true; maxretry = 5; bantime = "10m"; ignoreIP = [ "127.0.0.1/8" "192.168.122.0/24" ];};maxretry = 5: bannir après 5 échecsbantime = "10m": durée du bannissementignoreIP: ne jamais bannir ces réseaux (votre réseau local)
Configurer le firewall
Section intitulée « Configurer le firewall »Le firewall NixOS est activé par défaut, mais bloquer explicitement tout sauf le nécessaire renforce la sécurité :
networking.firewall = { enable = true; allowedTCPPorts = [ 22 ];};Seul le port 22 (SSH) est ouvert. Toute connexion entrante sur un autre port est rejetée.
Appliquer et vérifier
Section intitulée « Appliquer et vérifier »cd /etc/nixosgit add -A && git commit -m "add fail2ban and firewall"sudo nixos-rebuild switch --flake .#nixos-labVérifications :
# fail2ban actif ?systemctl is-active fail2ban# active
# Règles firewall ?sudo iptables -L nixos-fw -n# Chain nixos-fw (1 references)# target prot opt source destination# nixos-fw-accept tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22# nixos-fw-log-refuse all -- 0.0.0.0/0 0.0.0.0/0Gérer les utilisateurs et les groupes
Section intitulée « Gérer les utilisateurs et les groupes »Créer un utilisateur
Section intitulée « Créer un utilisateur »users.users.dev = { isNormalUser = true; description = "Développeur"; extraGroups = [ "wheel" ]; openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAA... votre-cle-publique" ];};isNormalUser = true: crée un home directory et un shell standardextraGroups = [ "wheel" ]: accès sudoopenssh.authorizedKeys.keys: connexion SSH par clé (pas de mot de passe)
Après nixos-rebuild switch, vérifiez :
# L'utilisateur existe ?id dev# uid=1001(dev) gid=100(users) groupes=100(users),1(wheel)
# Connexion SSH depuis l'hôte ?ssh dev@192.168.122.104 whoami# devSupprimer un utilisateur
Section intitulée « Supprimer un utilisateur »Retirez simplement le bloc users.users.dev de la configuration et appliquez. NixOS désactive le compte, mais ne supprime pas le home directory par sécurité.
Comprendre switch, test et boot
Section intitulée « Comprendre switch, test et boot »nixos-rebuild propose trois modes d’application :
| Commande | Effet immédiat | Boot suivant | Génération créée |
|---|---|---|---|
switch | Oui — active immédiatement | Oui | Oui |
test | Oui — active immédiatement | Non — revient à l’ancienne | Non |
boot | Non — rien ne change | Oui — active au reboot | Oui |
Quand utiliser chacun
Section intitulée « Quand utiliser chacun »test: vous voulez vérifier qu’un changement fonctionne avant de le rendre permanent. Si le système plante, un reboot revient à l’état précédent.switch: le cas standard — appliquer immédiatement et rendre permanent.boot: changement de noyau ou de bootloader — vous voulez que ça prenne effet au prochain reboot sans perturber le système en cours.
# Tester d'abord (recommandé pour les changements risqués)sudo nixos-rebuild test --flake .#nixos-lab
# Si tout va bien, appliquersudo nixos-rebuild switch --flake .#nixos-labLire le diff de génération
Section intitulée « Lire le diff de génération »Avant d’appliquer un changement, vous pouvez voir exactement ce qui va changer en termes de paquets :
nix profile diff-closures --profile /nix/var/nix/profiles/systemRésultat (extrait) :
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 KiBChaque transition montre les paquets ajoutés (∅ → version), supprimés (version → ∅) et mis à jour (ancienne → nouvelle). C’est l’équivalent d’un git diff pour votre système.
Lister les générations
Section intitulée « Lister les générations »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 nixos-rebuild switch crée une nouvelle génération. Vous pouvez revenir à n’importe laquelle depuis le boot loader — c’est le sujet du Lab 9.
Organiser la configuration en modules
Section intitulée « Organiser la configuration en modules »Quand configuration.nix grossit, découpez-le en fichiers thématiques. NixOS fusionne automatiquement tous les modules importés.
Créer network.nix
Section intitulée « Créer network.nix »Extrayez tout ce qui concerne le réseau et la sécurité réseau :
{ config, ... }:{ networking.hostName = "nixos-lab"; networking.networkmanager.enable = true;
networking.firewall = { enable = true; allowedTCPPorts = [ 22 ]; };
services.openssh = { enable = true; settings = { PermitRootLogin = "prohibit-password"; PasswordAuthentication = false; }; };
services.fail2ban = { enable = true; maxretry = 5; bantime = "10m"; ignoreIP = [ "127.0.0.1/8" "192.168.122.0/24" ]; };}Créer users.nix
Section intitulée « Créer users.nix »Extrayez la gestion des utilisateurs :
{ config, ... }:{ users.users.lab = { isNormalUser = true; extraGroups = [ "wheel" ]; openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAA... votre-cle-publique" ]; };
users.users.dev = { isNormalUser = true; description = "Développeur"; extraGroups = [ "wheel" ]; openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAA... votre-cle-publique" ]; };
security.sudo.wheelNeedsPassword = false;}Simplifier configuration.nix
Section intitulée « Simplifier configuration.nix »Le fichier principal ne contient plus que le socle :
{ config, pkgs, modulesPath, ... }:{ imports = [ (modulesPath + "/profiles/qemu-guest.nix") ./network.nix ./users.nix ];
boot.loader.systemd-boot.enable = true; boot.loader.efi.canTouchEfiVariables = true; boot.initrd.availableKernelModules = [ "virtio_pci" "virtio_blk" "virtio_scsi" "ahci" "sd_mod" ]; boot.kernelModules = [ "virtio_net" ];
time.timeZone = "Europe/Paris"; i18n.defaultLocale = "fr_FR.UTF-8"; console.keyMap = "fr";
environment.systemPackages = with pkgs; [ vim git htop curl tmux ];
nix.settings.experimental-features = [ "nix-command" "flakes" ];
nix.gc = { automatic = true; dates = "weekly"; options = "--delete-older-than 30d"; };
system.stateVersion = "25.11";}Appliquez et vérifiez que tout fonctionne identiquement :
cd /etc/nixosgit add -A && git commit -m "refactor: split into network.nix and users.nix"sudo nixos-rebuild switch --flake .#nixos-labNixOS fusionne les trois fichiers au moment de l’évaluation. Le résultat est strictement identique à un fichier monolithique — les services et utilisateurs sont préservés.
hardware-configuration.nix : ce qu’il contient
Section intitulée « hardware-configuration.nix : ce qu’il contient »Si vous avez suivi le Lab 2 (installation sans disko), vous avez un fichier hardware-configuration.nix généré par nixos-generate-config. Il contient :
- Les modules noyau nécessaires au matériel détecté (virtio, ahci, etc.)
- Les points de montage avec les UUID des partitions
- Le profil de virtualisation (
qemu-guest.nixpour les VM KVM)
# Exemple généré{ config, lib, pkgs, modulesPath, ... }:{ imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "virtio_blk" ];
fileSystems."/" = { device = "/dev/disk/by-uuid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; fsType = "ext4"; };
fileSystems."/boot" = { device = "/dev/disk/by-uuid/XXXX-XXXX"; fsType = "vfat"; };}Vérifications
Section intitulée « Vérifications »-
fail2ban est actif
Fenêtre de terminal systemctl is-active fail2ban# active -
Le firewall n’autorise que le port 22
Fenêtre de terminal sudo iptables -L nixos-fw -n# nixos-fw-accept tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22# nixos-fw-log-refuse all -- 0.0.0.0/0 0.0.0.0/0 -
Le second utilisateur fonctionne
Fenêtre de terminal id dev# uid=1001(dev) gid=100(users) groupes=100(users),1(wheel)ssh dev@192.168.122.104 whoami# dev -
La factorisation en modules est transparente
Fenêtre de terminal ls /etc/nixos/*.nix# configuration.nix disko-config.nix flake.nix network.nix users.nixsudo nixos-rebuild switch --flake .#nixos-lab# Done. The new configuration is /nix/store/... -
Les générations sont visibles
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) -
Le diff de génération montre les changements
Fenêtre de terminal nix profile diff-closures --profile /nix/var/nix/profiles/system# Version 2 -> 3:# fail2ban: ∅ → 1.1.0, +5144.9 KiB
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
nixos-rebuild : « error: attribute ‘xxx’ missing » | Option mal orthographiée | Vérifier avec nixos-option ou search.nixos.org |
Un service n’est pas actif après switch | L’option enable = true est absente | Ajouter services.<name>.enable = true |
| Firewall bloque un service légitime | Port non déclaré | Ajouter le port à networking.firewall.allowedTCPPorts |
hardware-configuration.nix modifié par erreur | Modification manuelle | sudo nixos-generate-config pour régénérer |
| Conflit entre deux modules (même option) | Deux fichiers définissent la même option avec des valeurs incompatibles | Utiliser lib.mkForce ou lib.mkDefault pour la priorité, ou regrouper l’option dans un seul module |
nixos-rebuild test fonctionne mais switch échoue | Problème d’écriture du bootloader | Vérifier que /boot est monté et que canTouchEfiVariables = true |
| Nouveau paquet absent du PATH | nix-rebuild switch pas exécuté | Relancer sudo nixos-rebuild switch --flake .#hostname |
À retenir
Section intitulée « À retenir »configuration.nixest une fonction Nix qui décrit l’état complet du système — chaque ligne correspond à une option NixOS documentéenixos-optionet search.nixos.org sont les deux outils de référence pour découvrir et comprendre les options disponibles- Ajouter un service = déclarer
services.<name>.enable = true+ les options souhaitées, puisnixos-rebuild switch nixos-rebuild testapplique sans rendre permanent — idéal pour valider un changement risqué avantswitchnix profile diff-closuresmontre exactement ce qui change entre deux générations — utilisez-le avant chaque switch important- Factorisez en modules dès que la configuration dépasse 100 lignes — NixOS fusionne automatiquement tous les imports
- Ne créez jamais rien de façon impérative (
useradd,apt install) — tout changement non déclaré sera perdu au prochainswitch