Files
nixos-workstations/modules/homed.nix
T

132 lines
4.3 KiB
Nix

{ 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
{
options.nixosWorkstations.homedUser = {
enable = lib.mkEnableOption "précréation d'un utilisateur systemd-homed chiffré";
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.";
};
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" ];
};
};
}