Téléverser les fichiers vers "modules"

This commit is contained in:
2026-08-19 15:25:01 +02:00
parent 16ebd52f79
commit 2cd26b4ce1
4 changed files with 278 additions and 241 deletions
+123 -65
View File
@@ -1,73 +1,131 @@
{ config, ... }:
{ config, lib, pkgs, ... }:
let
cfg = config.nixosWorkstations.homedUser;
# LAB : le mot de passe initial est volontairement un mot de passe par défaut
# connu. Il ne constitue pas un secret durable : Alice doit le remplacer lors
# de sa première session. Pour une future version production, ce credential
# devra venir d'une source chiffrée/externe et non du Nix store.
initialPasswordCredential = pkgs.writeText
"nixos-workstations-${cfg.user}-initial-password"
cfg.initialPassword;
provisionService = "nixos-workstations-provision-${cfg.user}";
in
{
#
# systemd-homed
#
# Les utilisateurs finaux sont gérés par systemd-homed et non par
# users.users.<name>.
#
# Leur home pourra être stocké dans un volume LUKS2 individuel.
#
services.homed.enable = true;
options.nixosWorkstations.homedUser = {
enable = lib.mkEnableOption "précréation d'un utilisateur systemd-homed chiffré";
#
# NixOS possède des utilisateurs système nixbld avec des UID > 1000.
#
# Cela déclenche un avertissement de systemd-userdb concernant
# l'existence d'utilisateurs "réguliers".
#
# Dans notre architecture ce warning n'est pas pertinent :
# les utilisateurs homed sont créés explicitement avec homectl.
#
services.userdbd.silenceHighSystemUsers = true;
#
# SDDM + systemd-homed
#
# systemd-homed utilise des UID dynamiques élevés.
# La plage réservée aux utilisateurs homed monte jusqu'à 60513.
#
# NixOS configure normalement SDDM avec MaximumUid = nixbld,
# soit environ 30000, ce qui exclurait Alice (UID 60456 dans notre test).
#
services.displayManager.sddm.settings = {
Users = {
MinimumUid = 1000;
MaximumUid = 60513;
user = lib.mkOption {
type = lib.types.str;
default = "alice";
description = "Compte systemd-homed à préparer automatiquement.";
};
realName = lib.mkOption {
type = lib.types.str;
default = "Alice";
description = "Nom complet de l'utilisateur systemd-homed.";
};
#
# IMPORTANT :
#
# SDDM construit sa liste d'utilisateurs dans sddm-greeter avec
# getpwent().
#
# Sous NixOS, libnss_systemd.so n'est pas dans le chemin standard
# du linker. Le chemin des modules NSS est fourni par :
#
# config.system.nssModules.path
#
# Notre test a confirmé que :
#
# LD_LIBRARY_PATH=<nssModules.path>
# getent -s systemd passwd
#
# permet immédiatement d'énumérer Alice.
#
# GreeterEnvironment est le mécanisme SDDM prévu pour transmettre
# ces variables au processus sddm-greeter.
#
# On conserve également la variable nécessaire au greeter
# KDE/Wayland de NixOS.
#
General = {
GreeterEnvironment =
"QT_WAYLAND_SHELL_INTEGRATION=layer-shell,LD_LIBRARY_PATH=${config.system.nssModules.path}";
initialPassword = lib.mkOption {
type = lib.types.str;
default = "LaboTest@1980";
description = "Mot de passe temporaire utilisé uniquement pour le premier accès LAB.";
};
diskSize = lib.mkOption {
type = lib.types.str;
default = "10G";
description = "Taille initiale du conteneur LUKS2 du home.";
};
};
}
config = lib.mkIf cfg.enable {
services.homed.enable = true;
# Les comptes nixbld NixOS ont des UID > 1000. Nous n'utilisons pas le
# workflow first-boot de homed : les comptes sont créés explicitement par
# le service ci-dessous.
services.userdbd.silenceHighSystemUsers = true;
# SDDM doit accepter la plage d'UID systemd-homed et son greeter doit
# charger libnss_systemd directement. Cette configuration a été validée en
# LAB : sans ce LD_LIBRARY_PATH, getpwent() n'énumère pas Alice sous NixOS.
services.displayManager.sddm.settings = {
Users = {
MinimumUid = 1000;
MaximumUid = 60513;
};
General = {
GreeterEnvironment =
"QT_WAYLAND_SHELL_INTEGRATION=layer-shell,LD_LIBRARY_PATH=${config.system.nssModules.path}";
};
};
# Précréation automatique d'Alice. localadm ne lance qu'un
# nixos-rebuild switch : ce service est démarré automatiquement et ne fait
# rien si le compte homed existe déjà.
#
# RemainAfterExit est volontairement conservé : SDDM dépend de la réussite
# de ce service au démarrage. Le script lui-même reste idempotent.
systemd.services.${provisionService} = {
description = "Prépare le compte systemd-homed ${cfg.user}";
wantedBy = [ "multi-user.target" ];
before = [ "display-manager.service" ];
after = [ "systemd-homed.service" ];
requires = [ "systemd-homed.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
LoadCredential = [
"home.new-password:${initialPasswordCredential}"
];
};
path = [
pkgs.coreutils
pkgs.getent
pkgs.systemd
];
script = ''
set -eu
user=${lib.escapeShellArg cfg.user}
if ${pkgs.systemd}/bin/homectl inspect "$user" >/dev/null 2>&1; then
echo "Compte homed $user déjà présent : aucune modification."
exit 0
fi
# Refuser une collision avec un compte UNIX classique du même nom.
if ${pkgs.getent}/bin/getent passwd "$user" >/dev/null 2>&1; then
echo "ERREUR : $user existe déjà mais n'est pas un compte systemd-homed." >&2
exit 1
fi
echo "Création du compte systemd-homed $user et de son home LUKS2..."
${pkgs.systemd}/bin/homectl --no-ask-password create "$user" \
--real-name=${lib.escapeShellArg cfg.realName} \
--storage=luks \
--fs-type=ext4 \
--disk-size=${lib.escapeShellArg cfg.diskSize} \
--access-mode=0700 \
--shell=/run/current-system/sw/bin/bash \
--password-change-now=no \
--recovery-key=no
'';
};
# Au boot, le compte doit exister avant le lancement du greeter SDDM.
systemd.services.display-manager = {
after = [ "${provisionService}.service" ];
requires = [ "${provisionService}.service" ];
};
};
}