132 lines
4.3 KiB
Nix
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" ];
|
|
};
|
|
};
|
|
}
|