État LAB v1.7 / Étape 2 : systemd-homed + LUKS2 pour Alice. L'enrôlement FIDO2 dans le home viendra à l'étape 3.

🛡️ NixOS Workstations

Déploiement industrialisé de postes de travail NixOS sécurisés

NixOS KDE Plasma Security Deployment Status License

Une base déclarative et reproductible pour déployer, sécuriser et maintenir des environnements de bureau NixOS homogènes.


🎯 Objectif

NixOS Workstations fournit un socle commun permettant de construire un parc de postes de travail NixOS avec :

  • 🧬 une configuration déclarative versionnée dans Git ;
  • 📦 un ensemble logiciel homogène ;
  • 🖥️ KDE Plasma 6 ;
  • 👤 des comptes locaux maîtrisés ;
  • 🔐 une authentification locale de secours ;
  • 🔑 FIDO2 / YubiKey ;
  • une finalisation graphique du poste lors de la première utilisation ;
  • 💻 une séparation stricte entre configuration commune et matériel propre à chaque machine.
                 ┌───────────────────────────┐
                 │          Git              │
                 │    nixos-workstations     │
                 └─────────────┬─────────────┘
                               │
              ┌────────────────┼────────────────┐
              │                │                │
              ▼                ▼                ▼
       📦 Logiciels      👤 Utilisateurs    🛡️ Sécurité
              │                │                │
              └────────────────┼────────────────┘
                               │
                               ▼
                     🖥️ NixOS + KDE Plasma
                               │
                        🔐 Mot de passe
                        🔑 FIDO2 / YubiKey
                               │
                               ▼
                       ✅ Poste opérationnel

Principes

Principe Objectif
🧬 Déclaratif Décrire l'état attendu du poste dans Git
♻️ Reproductible Reconstruire un poste de manière cohérente
🧱 Modulaire Séparer logiciels, utilisateurs, sécurité et UX
🔐 Natif NixOS Utiliser les mécanismes système plutôt que les contourner
🔑 FIDO2 Utiliser une clé de sécurité comme moyen d'authentification principal
🧰 Industrialisable Éviter les fichiers de configuration complets spécifiques à chaque poste
🧪 Validation progressive builddry-activatetestswitch

🏗️ Architecture

nixos-workstations/
├── configuration.nix
├── LICENSE
├── COMMERCIAL-LICENSE.md
├── PRODUCTION-CHECKLIST.md
│
├── workstation-setup/
│   ├── CMakeLists.txt
│   ├── org.raspot.nixosworkstations.setup.desktop
│   └── src/
│       ├── CMakeLists.txt
│       ├── main.cpp
│       ├── Main.qml
│       ├── ProvisioningBackend.h
│       └── ProvisioningBackend.cpp
│
└── modules/
    ├── software.nix
    ├── users.nix
    ├── security.nix
    └── workstation-setup.nix

💻 Matériel propre à chaque poste

Le fichier généré lors de l'installation reste local à la machine :

/etc/nixos/hardware-configuration.nix

Il n'est pas partagé dans le dépôt commun.

imports = [
  /etc/nixos/hardware-configuration.nix
  ./modules/software.nix
  ./modules/users.nix
  ./modules/security.nix
  ./modules/workstation-setup.nix
];

Les UUID de partitions et autres informations propres au matériel ne peuvent ainsi pas écraser la configuration d'un autre poste.


🧩 Modules

📦 software.nix

Déploie l'environnement logiciel commun : Chromium, Firefox ESR, OnlyOffice, Teams, Outlook Web, Git et les outils FIDO2 nécessaires.

👤 users.nix

Décrit les comptes locaux et leurs rôles. Les mots de passe restent mutables afin que l'utilisateur puisse personnaliser son secret local avec passwd.

Dans ce lab, le mot de passe temporaire d'alice est volontairement déclaré dans users.nix avec initialHashedPassword.

Mot de passe temporaire du lab : LaboTest@1980

Avec users.mutableUsers = true, ce hash sert à la création initiale du compte. Une fois le mot de passe changé par l'utilisateur, les activations suivantes conservent le nouveau mot de passe local.

Pour un déploiement réel, le dépôt sera privé et la stratégie de secret initial pourra être adaptée au processus d'exploitation.

🛡️ security.nix

Étape 1 LAB : conserve uniquement les règles daccès à la YubiKey. Aucun mapping U2F et aucune authentification PAM/FIDO2 ne sont activés ; lenrôlement sera pris en charge ultérieurement par systemd-homed.

workstation-setup.nix

Déploie l'assistant plein écran de finalisation du poste et son lancement automatique pour l'utilisateur concerné.

Le nom de l'utilisateur n'est pas codé dans l'application : il est déclaré dans la configuration NixOS :

nixosWorkstations.workstationSetup = {
  enable = true;
  user = "alice";
};

Finalisation du poste

Lors de la première ouverture de session de l'utilisateur :

👋 Bienvenue → 🔐 Mot de passe → 🔑 YubiKey →  Poste prêt

🔐 Mot de passe local

  • 👁️ affichage/masquage des champs ;
  • 📊 indicateur de robustesse purement informatif ;
  • mot de passe actuel obligatoire ;
  • confirmation du nouveau mot de passe ;
  • 🟢 aucun blocage UI lié à une robustesse jugée faible ;
  • 🔒 changement réel effectué par /run/wrappers/bin/passwd.

🔑 PIN YubiKey

  • 👁️ affichage/masquage du PIN ;
  • PIN temporaire obligatoire ;
  • choix et confirmation du nouveau PIN ;
  • 🔐 changement réel effectué par ykman fido access change-pin ;
  • ⚠️ aucune boucle automatique en cas de mauvais PIN.

🚪 Assistant obligatoire

Tant que les deux opérations n'ont pas réellement réussi :

  • le bouton final n'est pas disponible ;
  • une fermeture classique de la fenêtre est refusée ;
  • une minimisation est immédiatement ramenée en plein écran ;
  • l'assistant sera reproposé à la prochaine ouverture de session si la configuration reste incomplète.

Les étapes ne sont considérées terminées qu'après création des marqueurs :

~/.local/state/nixos-workstations/password-initialized
~/.local/state/nixos-workstations/yubikey-pin-created

🛡️ Traitement des secrets

┌───────────────────────────────┐
│       Qt Quick / QML          │
│      saisie utilisateur       │
└───────────────┬───────────────┘
                │ pipe privé
                ▼
┌───────────────────────────────┐
│      backend Qt contrôlé      │
└───────────────┬───────────────┘
                │
       ┌────────┴────────┐
       ▼                 ▼
/run/wrappers/bin/    ykman FIDO2
     passwd
       │                 │
       ▼                 ▼
  /etc/shadow         YubiKey

Principes retenus :

  • 🚫 aucun mot de passe ou PIN dans les arguments de processus ;
  • 🚫 aucun secret définitif utilisateur écrit dans Git ;
  • 🧪 le mot de passe temporaire du lab est volontairement versionné dans users.nix ;
  • 🚫 aucune modification directe de /etc/shadow ;
  • 🚫 aucun module PAM artisanal ;
  • 🚫 aucun reset automatique de YubiKey ;
  • wrapper passwd fourni par NixOS ;
  • outil Yubico officiel pour FIDO2 ;
  • logs des helpers désactivés ;
  • core dumps désactivés pendant le provisioning ;
  • une seule tentative FIDO2 par validation utilisateur.

🔐 Mot de passe temporaire du lab

Le compte alice est créé avec un mot de passe temporaire connu pour faciliter les essais reproductibles :

LaboTest@1980

Son hash est déclaré directement dans :

modules/users.nix

L'assistant demande ensuite à l'utilisateur de remplacer ce mot de passe temporaire par son mot de passe personnel. Avec users.mutableUsers = true, le nouveau mot de passe est conservé lors des activations suivantes.

Cette décision est volontaire pour le lab. Elle évite une étape locale supplémentaire avant chaque nouvelle installation de test.


🧪 Déploiement

1. Construction

sudo nixos-rebuild build \
  -I nixos-config=/home/localadm/nixos-workstations/configuration.nix

2. Simulation d'activation

sudo nixos-rebuild dry-activate \
  -I nixos-config=/home/localadm/nixos-workstations/configuration.nix

3. Test temporaire

sudo nixos-rebuild test \
  -I nixos-config=/home/localadm/nixos-workstations/configuration.nix

4. Activation persistante

Après validation complète de la checklist :

sudo nixos-rebuild switch \
  -I nixos-config=/home/localadm/nixos-workstations/configuration.nix

👉 Voir PRODUCTION-CHECKLIST.md avant un switch.


🔭 Industrialisation future

Le socle est conçu pour évoluer vers :

Inventaire / GLPI / CSV
        │
        ▼
Utilisateur + poste + profil matériel
        │
        ▼
Configuration NixOS commune
        │
        ▼
Installation automatisée
        │
        ▼
Finalisation utilisateur FIDO2

Les prochaines briques possibles sont notamment Disko, un inventaire machines/utilisateurs et une installation unattended.


⚖️ Licence

Le projet est distribué sous PolyForm Noncommercial 1.0.0.

utilisation et modification non commerciales selon les conditions de la licence ;
🚫 exploitation commerciale sans autorisation ;
💼 une exploitation commerciale peut faire l'objet d'un accord séparé avec le titulaire des droits.

Voir LICENSE et COMMERCIAL-LICENSE.md.

Cette licence est source-available non commerciale ; elle n'est pas une licence Open Source au sens OSI.


Correctifs v1.2 du setup

La version 1.2 durcit la brique workstation-setup :

  • l'utilisateur cible n'est plus compilé dans le binaire ; le lanceur le transmet avec --target-user ;
  • les chemins des helpers sont générés dans Config.h, sans macro CMake fragile ;
  • le binaire ne quitte plus silencieusement en cas de mauvais utilisateur ;
  • --diagnose affiche l'utilisateur courant, l'utilisateur cible et l'état des marqueurs ;
  • un journal sans secret est écrit dans ~/.local/state/nixos-workstations/setup.log ;
  • les buffers explicites contenant des secrets sont effacés dès que possible ;
  • les timeouts des helpers sont distingués des autres erreurs ;
  • programs.yubikey-manager.enable = true fournit ykman avec les règles udev NixOS nécessaires ;
  • une seule invocation de ykman est effectuée par tentative de changement de PIN.

Diagnostic manuel :

nixos-workstations-setup --target-user alice --diagnose

Lancement manuel de l'interface :

nixos-workstations-setup --target-user alice

Correctif v1.2 — contrôle de lutilisateur

La v1.1 pouvait refuser alice tout en affichant alice comme utilisateur courant et cible à cause dun ordre dinitialisation incorrect des membres C++. La v1.2 supprime l’état dautorisation mémorisé et vérifie directement lUID effectif du processus par rapport à lUID du compte cible. La compilation traite également les avertissements reorder comme des erreurs.

Correctif v1.3 — changement de mot de passe avec PAM/U2F

La configuration conserve U2F pour les services PAM dauthentification, mais le désactive explicitement pour le service passwd avec security.pam.services.passwd.u2f.enable = false;. Cela évite que le changement de mot de passe lancé par lassistant soit intercepté par pam_u2f. Le message de timeout est également spécifique à l’étape en cours : mot de passe ou YubiKey.

Correctif v1.4 — dialogue PAM passwd

Le helper de mot de passe accepte désormais l'invite PAM générique Password: pour l'authentification initiale. Les étapes sont suivies explicitement et les erreurs techniques sont journalisées sans secret.

Correctif v1.5 — changement de PIN FIDO2 direct

La v1.5 n'utilise plus expect pour piloter les invites texte de ykman lors du changement de PIN. Le helper utilise directement python-fido2 et ClientPin.change_pin() sur l'interface CTAP2 de la clé. Les secrets sont transmis au helper par stdin, jamais dans les arguments du processus. Une seule tentative CTAP2 est effectuée par validation.

Étape 1 v1.6 — YubiKey vierge

Cette version valide uniquement l'initialisation d'une YubiKey FIDO2 vierge :

  • aucun PIN FIDO2 initial ;
  • aucun u2f-mappings dans Git ou /etc ;
  • aucun pam_u2f actif ;
  • le setup demande uniquement le nouveau PIN et sa confirmation ;
  • ClientPin.set_pin() crée le premier PIN ;
  • si un PIN existe déjà, l'opération est refusée sans tentative de PIN ;
  • le mot de passe local continue de fonctionner comme dans la v1.5.

L'authentification FIDO2 du compte et le chiffrement LUKS2 ne font volontairement pas partie de cette étape.

S
Description
No description provided
Readme
513 KiB
Languages
QML 39.5%
C++ 36.6%
Nix 21.9%
CMake 1.8%
C 0.2%