Modules système
⚙ darkone.system.core
Section intitulée « ⚙ darkone.system.core »Module principal de DNF.
Configure le chargeur systemd-boot, le noyau LTS (ou le dernier noyau stable via
enableLatestKernel), la JetBrains Mono Nerd
Font (avec kmscon pour le TTY), l’optimisation nocturne du magasin Nix et
la collecte hebdomadaire des ordures (rétention de 30 jours, ou keep-last-N via
gcKeepGenerations sur les hôtes à espace disque limité), le pare-feu, la
politique de veille (les serveurs peuvent la désactiver complètement via
disableSuspend), les règles polkit
autorisant le groupe wheel à arrêter/redémarrer, et un groupe/utilisateur
common-files partagé pour les dossiers médias inter-services.
- enable
boolSystème principal du framework Darkone (activé par défaut) - enableSystemdBoot
boolActiver le chargeur de démarrage par défaut - enableLatestKernel
boolUtiliser le dernier noyau stable (linuxPackages_latest) au lieu du noyau LTS - enableFstrim
boolOptimisation SSD avec fstrim - enableFirewall
boolActiver le pare-feu (vrai par défaut) - enableSops
boolActiver le module sops dnf (vrai par défaut) - enableFlatpak
boolActiver la configuration flatpak DNF (uniquement pour les environnements graphiques) - enableKmscon
boolActiver la nerd font pour le TTY - gcKeepGenerations
intLorsque > 0, tronquer le profil système aux N dernières générations avant chaque collecte des ordures, et collecter quotidiennement sans rétention basée sur l’âge. Pour les hôtes avec une partition racine serrée (passerelles). - enableBoost
boolActiver l’overclocking, corectl - enableAutoSuspend
boolActiver la veille automatique (pour les portables, ignoré si disableSuspend est vrai) - disableSuspend
boolDésactivation complète de la veille (pour les serveurs) - enableCommonFilesUser
boolActiver l’utilisateur common-files utilisé par plusieurs services
darkone.system.core = { enable = true; enableSystemdBoot = true; enableLatestKernel = false; enableFstrim = true; enableFirewall = true; enableSops = true; enableFlatpak = true; enableKmscon = true; gcKeepGenerations = 5; enableBoost = false; enableAutoSuspend = false; disableSuspend = false; enableCommonFilesUser = false;};⚙ darkone.system.documentation
Section intitulée « ⚙ darkone.system.documentation »Documentation (man) pour les développeurs et les administrateurs.
- enable
boolActiver la documentation technique utile (man, nixos)
darkone.system.documentation.enable = false;⚙ darkone.system.hardware
Section intitulée « ⚙ darkone.system.hardware »Améliorations de la configuration matérielle.
- enable
boolActiver les optimisations matérielles - enableIntel
boolActiver les mises à jour du microcode Intel - enableAmd
boolActiver les mises à jour du microcode AMD
darkone.system.hardware = { enable = false; enableIntel = false; enableAmd = false;};⚙ darkone.system.i18n
Section intitulée « ⚙ darkone.system.i18n »Configuration de la localisation et de la langue.
- enable
boolActiver i18n avec la configuration de la zone de réseau par défaut - locale
strMatching localeRegexLocale réseau, doit correspondre à la formexx_YY.UTF-8. - timeZone
strFuseau horaire réseau
darkone.system.i18n = { enable = false; locale = "fr_FR.UTF-8"; timeZone = "Europe/Paris";};⚙ darkone.system.luks
Section intitulée « ⚙ darkone.system.luks »Politique de passphrase LUKS & déverrouillage distant : passphrases partagées et par hôte, SSH initrd.
Complète modules/system/yubikey.nix (keyslots FIDO2) avec le volet passphrase
de la politique LUKS de la flotte. Chaque volume chiffré porte exactement deux
passphrases gérées, plus un keyslot par YubiKey enrôlée :
| Keyslot | Secret | Audience |
|---|---|---|
| partagée | sops luks-passphrase | l’admin de la flotte. Autorise aussi les opérations de keyslot (luksAddKey / luksKillSlot) pour les unités ci-dessous, et c’est la clé avec laquelle disko formate le disque. |
| par-hôte | sops luks/<host>/passphrase | l’utilisateur de la machine en question, sans remettre la flotte en jeu. |
| FIDO2 | registry usr/secrets/yubikeys.json | un slot par clé, sur chaque hôte chiffré. |
Deux passphrases gérées et non une seule, car elles servent des personnes différentes — et parce qu’une rotation de l’une reste autorisée par l’autre : l’unité de synchronisation n’est jamais privée d’autoriseur (elle ajoute le nouveau slot avant de tuer l’ancien).
Il n’existe pas de « passphrase d’installation » distincte : just install formate
le volume via nixos-anywhere --disk-encryption-keys avec la passphrase partagée,
donc le keyslot de formatage est le keyslot partagé.
just luks <host> provisionne un hôte (idempotent, aussi appelé par just configure) ;
sa phase pre s’exécute hors ligne et est appelée par just install avant la
compilation. Il enregistre l’hôte dans le manifeste public
usr/secrets/luks.json (commité), stocke la passphrase par-hôte et la clé d’hôte
SSH de l’initrd dans sops, et garantit l’existence de la luks-passphrase partagée.
just luks <host> show affiche le tableau des keyslots et audite le déverrouillage
distant. Le module maintient ensuite tout converge à chaque apply :
- keyslots : un service oneshot synchronise les passphrases partagées et par-hôte dans chaque en-tête LUKS2 déclaré par disko. Une valeur sops modifiée fait tourner le keyslot correspondant (ancien slot tué, nouveau ajouté). Les opérations de keyslot sont autorisées par la passphrase gérée qui déverrouille encore le volume : l’une d’elles doit donc rester valide. Les slots hors de sa comptabilité (FIDO2, enrôlements manuels) ne sont jamais touchés.
- déverrouillage distant : sshd de l’initrd sur un port dédié (2222), propre
clé d’hôte persistante (
/var/lib/luks-initrd/), connexion root avec la clé de déploiementnix(usr/secrets/nix.pub).just unlock <host>répond à l’invite de passphrase sans humain (via l’aidednf-unlockembarquée dans l’initrd) ;just enter <host>est le chemin interactif. Les deux basculent sur l’IP WAN enregistrée dans le manifeste quand la route VPN est morte avec l’hôte. Les hôtes classiques utilisent DHCP sur les interfaces filaires (un portable en Wi-Fi n’a pas de réseau initrd et bascule sur le déverrouillage console) ; les passerelles de zone répliquent leur layout de production — IP LAN statique sur le bridge lan0, DHCP côté WAN — puisqu’elles sont elles-mêmes le serveur DHCP que leur initrd attendrait sinon.
- enable
boolPolitique de passphrase LUKS de la flotte (inerte jusqu’à ce quejust luks <host>provisionne l’hôte) - sshPort
portPort sshd de l’initrd ; distinct de 22 pour que la clé d’hôte de l’initrd n’entre jamais en conflit avec celle du système - volumes
listOf strVolumes LUKS déclarés par le layout disko de l’hôte.
darkone.system.luks = { enable = true; sshPort = 2222; volumes = [ ];};⚙ darkone.system.security
Section intitulée « ⚙ darkone.system.security »Durcissement système ANSSI BP-028 v2.0 (GNU/Linux). (wip)
Module recommandé, activé dans certains profils d’hôtes ou manuellement selon les besoins. Applique progressivement les recommandations ANSSI selon le niveau choisi et la catégorie de machine. Chaque profil d’hôte définit son niveau et sa catégorie :
darkone.system.security = { level = "intermediary"; # minimal | intermediary | reinforced | high category = "server"; # base | client | server};Les règles incompatibles avec l’environnement sont exclues par tag :
darkone.system.security.excludes = [ "needs-jit" "needs-hibernation" ];Une règle spécifique peut être contournée avec une justification obligatoire :
darkone.system.security.exceptions = { R9.rationale = "Docker rootless required during development.";};- enable
boolActiver le module de durcissement ANSSI BP-028 v2.0. - level
enum [ "minimal" "intermediary" "reinforced" "high" ]Niveau de durcissement ANSSI visé. - category
enum [ "base" "client" "server" ]Catégorie de machine qui sélectionne les sous-ensembles de règles. - excludes
listOf strTags qui désactivent des groupes entiers de règles. - exceptions
attrsExceptions par règle avec justification obligatoire. - adminMailbox
strAdresse e-mail de l’administrateur (sudo R39, alias MTA R75). - useHardenedKernel
boolUtiliser linuxPackages_hardened (R60, C1) au lieu du noyau par défaut. - allowedActiveUsers
listOf strComptes humains autorisés à s’authentifier (R30). Par défaut, chaque utilisateur déclaré dans config.yaml (host.users) plus le compte de déploiement du frameworknix. Les comptes désactivés (sans justificatif de mot de passe) et les comptes de service (qui ne sont pas des utilisateurs normaux) n’ont pas besoin d’être listés.
darkone.system.security = { enable = false; level = "minimal"; category = "base"; excludes = [ ]; exceptions = { }; adminMailbox = "admin@exemple.fr"; useHardenedKernel = false; allowedActiveUsers = [ ];};⚙ darkone.system.services
Section intitulée « ⚙ darkone.system.services »Enregistrement et configuration des services DNF.
- enable
boolActiver le gestionnaire de services DNF pour enregistrer et exposer les services - service
attrsConfiguration globale des services <nom>- enable
boolActiver le proxy de service - defaultParams
submoduleCes options sont calculées par dnfLib.srv.extractServiceParams- domain
strNom de domaine pour le service - title
strNom affiché sur la page d’accueil - description
strDescription du service pour la page d’accueil - icon
strNom de l’icône pour la page d’accueil 🡕 - global
boolService global accessible sur Internet - noRobots
boolEmpêcher les robots de scanner si global est vrai - fqdn
strFQDN calculé du service avant le proxy inverse - href
strURL calculée du service avant le proxy inverse - ip
strIP calculée pour contacter le service
- domain
- displayOnHomepage
boolAfficher un lien sur la page d’accueil - reverseProxy
boolAccessible via le proxy inverse de la passerelle de zone (DNS pointe vers l’IP LAN de la passerelle) - uniquePerZone
boolAu plus une instance autorisée par zone (validation du générateur) - externalAccess
boolService de zone www accessible depuis le LAN via une IP hôte fixe (p. ex. headscale, turn) - persist.dirs
listOf strRépertoires persistants du service - persist.files
listOf strFichiers persistants du service - persist.dbDirs
listOf strRépertoires persistants du service avec base(s) de données - persist.dbFiles
listOf strFichier(s) de base de données du service - persist.varDirs
listOf strFichiers secondaires variables (log, cache, etc.) - persist.mediaDirs
listOf strRépertoires média du service (images, vidéos, gros fichiers) - proxy.enable
boolCréer une configuration virtualHost (false pour les services qui gèrent la leur) - proxy.isProtected
boolService protégé par Oauth2 - proxy.allowedGroups
listOf strGroupes Kanidm autorisés sur ce service protégé (vide = tout utilisateur authentifié) - proxy.isInternal
boolLier le service sur l’interface interne uniquement (pas accessible depuis Internet) - proxy.hasReverseProxy
boolCeci est un proxy inverse (ou une autre configuration virtualHost via extraConfig) - proxy.defaultService
boolEst le service par défaut - proxy.servicePort
nullOr portPort interne du service - proxy.preExtraConfig
linesConfiguration virtualHost caddy supplémentaire (préfixe) - proxy.extraConfig
linesConfiguration virtualHost caddy supplémentaire - proxy.extraGlobalConfig
linesConfiguration caddy supplémentaire - proxy.scheme
strSchéma interne du service (http / https)
- enable
darkone.system.services = { enable = false; service.enable = false; service.defaultParams.domain = ""; service.defaultParams.title = ""; service.defaultParams.description = ""; service.defaultParams.icon = ""; service.defaultParams.global = false; service.defaultParams.noRobots = true; service.defaultParams.fqdn = ""; service.defaultParams.href = ""; service.defaultParams.ip = ""; service.displayOnHomepage = true; service.reverseProxy = true; service.uniquePerZone = false; service.externalAccess = false; service.persist.dirs = [ ]; service.persist.files = [ ]; service.persist.dbDirs = [ ]; service.persist.dbFiles = [ ]; service.persist.varDirs = [ ]; service.persist.mediaDirs = [ ]; service.proxy.enable = true; service.proxy.isProtected = false; service.proxy.allowedGroups = [ ]; service.proxy.isInternal = false; service.proxy.hasReverseProxy = true; service.proxy.defaultService = false; service.proxy.servicePort = null; service.proxy.preExtraConfig = ""; service.proxy.extraConfig = ""; service.proxy.extraGlobalConfig = ""; service.proxy.scheme = "https";};⚙ darkone.system.sops
Section intitulée « ⚙ darkone.system.sops »Gestion DNF de sops, mots de passe et secrets.
Branche sops-nix sur usr/secrets/secrets.yaml et le déverrouille avec la clé
SSH de l’hôte (ssh_host_ed25519_key) ainsi que la clé age d’infrastructure
dédiée (/etc/sops/age/infra.key). Déclare un
secret user/<login>/password-hash par utilisateur d’hôte, avec
neededForUsers = true afin que le hash soit disponible avant la création des
comptes utilisateurs.
Rien d’autre n’est matérialisé ici : un secret appartient aux hôtes qui le
consomment, déclaré par le module qui le lit. default-password-hash
reste dans le fichier chiffré, illisible par aucun hôte : il enregistre le
mot de passe par défaut de la flotte pour just passwd <login>.
- enable
boolActive la configuration automatisée de sops pour DNF
darkone.system.sops.enable = false;⚙ darkone.system.srv-dirs
Section intitulée « ⚙ darkone.system.srv-dirs »Service de gestion des répertoires partagés.
- enable
boolActiver les répertoires partagés, créer le répertoire racine (défaut /srv) - enableNfs
boolActiver les chemins du service NFS (nfs/common, nfs/homes) - enableMedias
boolActiver les chemins des services média (medias/[videos|music|incomming/…]) - enableStk
boolActiver le chemin de partage des pistes SuperTuxKart (nfs/stk-tracks) - root
strRépertoire racine des données persistantes (/srv) - nfs
strRépertoire racine NFS (/srv/nfs) - homes
strRépertoire des domiciles partagés (/srv/nfs/homes) - common
strRépertoire commun partagé (/srv/nfs/common lié à ~/Public) - stkTracks
strRépertoire des pistes SuperTuxKart partagées (/srv/nfs/stk-tracks) - medias
strRépertoire racine des médias (/srv/medias) - music
strRépertoire des fichiers musicaux partagés (/srv/medias/music) - videos
strRépertoire des fichiers vidéo partagés (/srv/medias/videos) - incoming
strRépertoire des fichiers entrants partagés (/srv/medias/incoming accès en écriture) - incomingMusic
strRépertoire des fichiers entrants partagés (/srv/medias/incoming/music accès en écriture) - incomingVideos
strRépertoire des fichiers entrants partagés (/srv/medias/incoming/videos accès en écriture)
darkone.system.srv-dirs = { enable = cfg.enableNfs || cfg.enableMedias || cfg.enableStk; enableNfs = false; enableMedias = false; enableStk = false; root = "/srv"; nfs = null; homes = null; common = null; stkTracks = null; medias = null; music = null; videos = null; incoming = null; incomingMusic = null; incomingVideos = null;};⚙ darkone.system.testing
Section intitulée « ⚙ darkone.system.testing »Mode test autonome pour le NixOS Test Driver.
Quand activé, neutralise les parties irréductiblement externes/exécution afin qu’un nœud puisse être testé dans une VM : headscale/tailscale deviennent des no-op et un certificat TLS fixe peut simuler ACME. Permet également à la configuration propre à workDir (nix.pub, harmonia.pub) d’être ignorée par core/nix-cache. sops reste RÉEL (haute fidélité).
- standalone
boolMode test autonome — ignore la configuration propre à workDir (nix.pub, harmonia.pub) et neutralise les services externes - tlsCert
nullOr pathCertificat auto-signé (PEM) fourni par le harnais de test pour simuler ACME. Jamais un chemin tests/ intégré dans le framework. - tlsKey
nullOr pathClé privée (PEM) associée à tlsCert.
darkone.system.testing = { standalone = false; tlsCert = null; tlsKey = null;};⚙ darkone.system.yubikey
Section intitulée « ⚙ darkone.system.yubikey »Authentification forte YubiKey : PAM U2F + FIDO2 LUKS déclaratif sur toute la flotte.
Un inscription physique par (utilisateur, clé) sur l’administrateur — just yubikey <user> [key] [action] — alimente :
- un registre public
usr/secrets/yubikeys.jsondans l’espace de travail consommateur : identifiant pamu2fcfg, identifiant et sel du FIDO2 hmac-secret (inutilisable sans la clé physique, donc commitable) ; - un secret sops
yubikey/<user>/<key>/luks-secret(la phrase secrète LUKS dérivée du FIDO2) ainsi que leluks-passphrasepartagé (la phrase secrète saisie lors de l’installation disko, nécessaire pour autoriser de nouveaux keyslots).
Le module propage ensuite tout de façon déclarative (just apply), sans jamais
brancher la clé sur les hôtes cible :
- login / sudo / greeter : pam_u2f en alternative au mot de passe
(
sufficient) : toucher la clé connecte, le mot de passe sops reste le repli automatique. Un identifiant est valide sur toute la flotte grâce à l’origine fixe (pam://<network.domain>). - hôtes chiffrés : un service oneshot inscrit automatiquement chaque clé
déclarée dans chaque en-tête LUKS2 déclaré par disko (keyslot +
systemd-fido2token, le format exact écrit parsystemd-cryptenroll) et purge les clés révoquées. La clé physique n’est nécessaire qu’au démarrage pour déverrouiller le disque.
- enable
boolAuthentification YubiKey (désactivé par défaut ; activé quand usr/secrets/yubikeys.json existe) - origin
strOrigine/appid pam_u2f fixe : une inscription est valide sur toute la flotte - luks.enable
boolDéverrouillage FIDO2 des volumes LUKS de l’hôte (inerte sans disko LUKS + clés inscrites)
darkone.system.yubikey = { enable = hasRegistry; origin = "pam://${network.domain}"; luks.enable = true;};