From c0fad3805c4c6b85528af6473a0015b2e2967b31 Mon Sep 17 00:00:00 2001 From: Olivier <1+olivier@noreply.raspot.in> Date: Wed, 19 Aug 2026 15:23:39 +0200 Subject: [PATCH] =?UTF-8?q?T=C3=A9l=C3=A9verser=20les=20fichiers=20vers=20?= =?UTF-8?q?"/"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 487 ++++++++++++------------------------------------------ 1 file changed, 108 insertions(+), 379 deletions(-) diff --git a/README.md b/README.md index 0ce4e13..70f5867 100644 --- a/README.md +++ b/README.md @@ -1,399 +1,128 @@ -> **État LAB v1.7 / Étape 2** : systemd-homed + LUKS2 pour Alice. L'enrôlement FIDO2 dans le home viendra à l'étape 3. +# NixOS Workstations — v1.8 LAB -
+Cette branche valide un poste NixOS/KDE dont le compte utilisateur est géré par `systemd-homed` et dont le home est chiffré en LUKS2. -# 🛡️ NixOS Workstations - -### Déploiement industrialisé de postes de travail NixOS sécurisés - -![NixOS](https://img.shields.io/badge/NixOS-26.05-5277C3?style=for-the-badge&logo=nixos&logoColor=white) -![KDE Plasma](https://img.shields.io/badge/KDE_Plasma-6-1D99F3?style=for-the-badge&logo=kde&logoColor=white) -![Security](https://img.shields.io/badge/Sécurité-FIDO2%20%2F%20YubiKey-111827?style=for-the-badge) -![Deployment](https://img.shields.io/badge/Déploiement-Déclaratif-7EBAE4?style=for-the-badge&logo=nixos&logoColor=white) -![Status](https://img.shields.io/badge/Statut-Candidat_Production-2563EB?style=for-the-badge) -![License](https://img.shields.io/badge/Licence-PolyForm_Noncommercial-F59E0B?style=for-the-badge) - -**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. +## Parcours cible ```text - ┌───────────────────────────┐ - │ Git │ - │ nixos-workstations │ - └─────────────┬─────────────┘ - │ - ┌────────────────┼────────────────┐ - │ │ │ - ▼ ▼ ▼ - 📦 Logiciels 👤 Utilisateurs 🛡️ Sécurité - │ │ │ - └────────────────┼────────────────┘ - │ - ▼ - 🖥️ NixOS + KDE Plasma - │ - 🔐 Mot de passe - 🔑 FIDO2 / YubiKey - │ - ▼ - ✅ Poste opérationnel +localadm + │ + └── nixos-rebuild switch + │ + ├── logiciels + ├── systemd-homed + ├── création automatique d'Alice + │ └── /home/alice.home → LUKS2 + └── SDDM + │ + ▼ + Alice se connecte avec + le mot de passe temporaire + │ + ▼ + assistant première session + │ + ┌───────┼────────────┐ + ▼ ▼ ▼ + nouveau PIN FIDO2 enrôlement + mot de vierge FIDO2 homed + passe + │ + ▼ + home déverrouillable par + mot de passe OU YubiKey+PIN ``` ---- +## Principes -## ✨ Principes +- `localadm` reste un compte NixOS classique d'administration locale. +- `alice` n'est jamais déclarée dans `users.users` : elle appartient exclusivement à `systemd-homed`. +- Le déploiement précrée Alice automatiquement avant SDDM. +- Le home d'Alice est `/home/alice.home`, conteneur LUKS2 monté sur `/home/alice` pendant la session. +- Aucun `pam_u2f`. +- Aucun `u2f-mappings`. +- La YubiKey démarre sans PIN ; Alice choisit son premier PIN. +- L'enrôlement FIDO2 est stocké dans le record `systemd-homed`. +- Le mot de passe reste un moyen de déverrouillage de secours. -| | 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** | `build` → `dry-activate` → `test` → `switch` | +## Déploiement LAB ---- - -## 🏗️ Architecture - -```text -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** : - -```text -/etc/nixos/hardware-configuration.nix -``` - -Il n'est pas partagé dans le dépôt commun. - -```nix -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`. - -```text -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 d’accès à la YubiKey. Aucun mapping U2F et aucune authentification PAM/FIDO2 ne sont activés ; l’enrô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 : - -```nix -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 : - -```text -~/.local/state/nixos-workstations/password-initialized -~/.local/state/nixos-workstations/yubikey-pin-created -``` - ---- - -## 🛡️ Traitement des secrets - -```text -┌───────────────────────────────┐ -│ 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 : +Le mot de passe temporaire est : ```text LaboTest@1980 ``` -Son hash est déclaré directement dans : +Il est volontairement connu pour le laboratoire et n'est pas un secret de production. + +Depuis `localadm` : + +```bash +cd ~/nixos-workstations +sudo nixos-rebuild switch -I nixos-config="$PWD/configuration.nix" +``` + +Un simple `nixos-rebuild build` construit la génération mais ne l'active pas ; il ne peut donc pas exécuter la précréation du compte sur le système courant. + +## Première connexion + +Alice sélectionne son compte dans SDDM et utilise le mot de passe temporaire. L'assistant se lance automatiquement et impose trois opérations réussies : + +1. remplacement du mot de passe temporaire ; +2. création du premier PIN sur une YubiKey FIDO2 vierge ; +3. enrôlement de cette YubiKey dans le home chiffré `systemd-homed`. + +Les secrets sont transmis aux helpers par stdin puis à `homectl` par le mécanisme `CREDENTIALS_DIRECTORY`. Aucun mot de passe ni PIN n'est placé dans les arguments de processus. + +## Recovery key + +La v1.8 **ne crée volontairement aucune recovery key avant ou pendant la première session**. Cela évite le problème validé en LAB où `homectl update` demandait la recovery key existante lors de la synchronisation des clés de chiffrement. + +L'ajout et l'escrow d'une recovery key d'administration feront l'objet d'une étape distincte. + +## SDDM et comptes homed sous NixOS + +Le greeter SDDM reçoit explicitement le chemin des modules NSS NixOS : + +```nix +services.displayManager.sddm.settings = { + Users = { + MinimumUid = 1000; + MaximumUid = 60513; + }; + General = { + GreeterEnvironment = + "QT_WAYLAND_SHELL_INTEGRATION=layer-shell,LD_LIBRARY_PATH=${config.system.nssModules.path}"; + }; +}; +``` + +Ce réglage est nécessaire sur le LAB pour que le greeter puisse énumérer Alice, dont l'UID `systemd-homed` est dans la plage 60001–60513. + +## Arborescence importante ```text -modules/users.nix +configuration.nix +modules/ +├── homed.nix +├── users.nix +├── security.nix +├── software.nix +└── workstation-setup.nix +workstation-setup/ +├── CMakeLists.txt +├── org.raspot.nixosworkstations.setup.desktop +└── src/ + ├── CMakeLists.txt + ├── Config.h.in + ├── Main.qml + ├── ProvisioningBackend.cpp + ├── ProvisioningBackend.h + └── main.cpp ``` -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. +`/etc/nixos/hardware-configuration.nix` reste local au poste et n'est pas versionné dans le dépôt partagé. -> Cette décision est volontaire pour le **lab**. Elle évite une étape locale supplémentaire avant chaque nouvelle installation de test. +## État LAB - ---- - -## 🧪 Déploiement - -### 1. Construction - -```bash -sudo nixos-rebuild build \ - -I nixos-config=/home/localadm/nixos-workstations/configuration.nix -``` - -### 2. Simulation d'activation - -```bash -sudo nixos-rebuild dry-activate \ - -I nixos-config=/home/localadm/nixos-workstations/configuration.nix -``` - -### 3. Test temporaire - -```bash -sudo nixos-rebuild test \ - -I nixos-config=/home/localadm/nixos-workstations/configuration.nix -``` - -### 4. Activation persistante - -Après validation complète de la checklist : - -```bash -sudo nixos-rebuild switch \ - -I nixos-config=/home/localadm/nixos-workstations/configuration.nix -``` - -👉 Voir [`PRODUCTION-CHECKLIST.md`](PRODUCTION-CHECKLIST.md) avant un `switch`. - ---- - -## 🔭 Industrialisation future - -Le socle est conçu pour évoluer vers : - -```text -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`](LICENSE) et [`COMMERCIAL-LICENSE.md`](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 : - -```bash -nixos-workstations-setup --target-user alice --diagnose -``` - -Lancement manuel de l'interface : - -```bash -nixos-workstations-setup --target-user alice -``` - - -### Correctif v1.2 — contrôle de l’utilisateur - -La v1.1 pouvait refuser `alice` tout en affichant `alice` comme utilisateur courant et cible à cause d’un ordre d’initialisation incorrect des membres C++. La v1.2 supprime l’état d’autorisation mémorisé et vérifie directement l’UID effectif du processus par rapport à l’UID 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 d’authentification, 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 l’assistant 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. +Le workflow doit encore être validé de bout en bout sur le poste réel avec la v1.8. Ne pas considérer cette archive comme une version production.