System modules
⚙ darkone.system.core
Section titled “⚙ darkone.system.core”The core DNF module.
Sets up the systemd-boot loader, the LTS kernel (or latest mainline via
enableLatestKernel), JetBrains Mono Nerd
Font (with kmscon for the TTY), nightly Nix store optimisation and
weekly garbage collection (30 d retention, or keep-last-N via
gcKeepGenerations on disk-constrained hosts), the firewall, suspend
policy (servers can fully disable it via disableSuspend), polkit
rules letting wheel halt/reboot, and a shared common-files
group/user for cross-service media folders.
- enable
boolDarkone framework core system (activated by default) - enableSystemdBoot
boolEnable the default boot loader - enableLatestKernel
boolUse the latest mainline kernel (linuxPackages_latest) instead of the LTS one - enableFstrim
boolSSD optimisation with fstrim - enableFirewall
boolEnable firewall (default true) - enableSops
boolEnable sops dnf module (default true) - enableFlatpak
boolEnable flatpak DNF configuration (only for graphic environments) - enableKmscon
boolEnable nerd font for TTY - gcKeepGenerations
intWhen > 0, trim the system profile to the last N generations before each garbage collection, and collect daily without age-based retention. For hosts with a tight root partition (gateways). - enableBoost
boolEnable overclocking, corectl - enableAutoSuspend
boolEnable automatic suspend (for laptops, ignored if disableSuspend is true) - disableSuspend
boolFull suspend disable (for servers) - enableCommonFilesUser
boolEnable the common-files user used by several 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 titled “⚙ darkone.system.documentation”Documentation (man) for developers and admins.
- enable
boolEnable useful technical documentation (man, nixos)
darkone.system.documentation.enable = false;⚙ darkone.system.hardware
Section titled “⚙ darkone.system.hardware”Hardware configuration improvements.
- enable
boolEnable hardware optimisations - enableIntel
boolEnable intel microcode updates - enableAmd
boolEnable amd microcode updates
darkone.system.hardware = { enable = false; enableIntel = false; enableAmd = false;};⚙ darkone.system.i18n
Section titled “⚙ darkone.system.i18n”Location and lang configuration.
- enable
boolEnable i18n with network zone configuration by default - locale
strMatching localeRegexNetwork locale, must match thexx_YY.UTF-8shape. - timeZone
strNetwork time zone
darkone.system.i18n = { enable = false; locale = "fr_FR.UTF-8"; timeZone = "Europe/Paris";};⚙ darkone.system.security
Section titled “⚙ darkone.system.security”ANSSI BP-028 v2.0 (GNU/Linux) system hardening. (wip)
Recommended module, enabled in certain host profiles or manually depending on needs. Progressively applies ANSSI recommendations according to the chosen level and machine category. Each host profile defines its level and category:
darkone.system.security = { level = "intermediary"; # minimal | intermediary | reinforced | high category = "server"; # base | client | server};Rules incompatible with the environment are excluded by tag:
darkone.system.security.excludes = [ "needs-jit" "needs-hibernation" ];A specific rule can be bypassed with a mandatory rationale:
darkone.system.security.exceptions = { R9.rationale = "Docker rootless required during development.";};- enable
boolEnable the ANSSI BP-028 v2.0 hardening module. - level
enum [ "minimal" "intermediary" "reinforced" "high" ]Targeted ANSSI hardening level. - category
enum [ "base" "client" "server" ]Machine category that selects rule subsets. - excludes
listOf strTags that disable entire rule groups. - exceptions
attrsPer-rule exceptions with mandatory rationale. - adminMailbox
strAdministrator email address (sudo R39, MTA aliases R75). - useHardenedKernel
boolUse linuxPackages_hardened (R60, C1) instead of the default kernel. - allowedActiveUsers
listOf strHuman accounts allowed to authenticate (R30). Defaults to every user declared in config.yaml (host.users) plus the framework deploy accountnix. Disabled accounts (no password credential) and service accounts (not normal users) need not be listed.
darkone.system.security = { enable = false; level = "minimal"; category = "base"; excludes = [ ]; exceptions = { }; adminMailbox = "admin@exemple.fr"; useHardenedKernel = false; allowedActiveUsers = [ ];};⚙ darkone.system.services
Section titled “⚙ darkone.system.services”DNF Service registration and configuration.
- enable
boolEnable DNF services manager to register and expose services - service
attrsGlobal services configuration <name>- enable
boolEnable service proxy - defaultParams
submoduleTheses options are calculated by dnfLib.srv.extractServiceParams- domain
strDomain name for the service - title
strDisplay name in homepage - description
strService description for homepage - icon
strIcon name for homepage 🡕 - global
boolGlobal service is accessible on Internet - noRobots
boolPrevent robots from scanning if global is true - fqdn
strCalculated FQDN or the service before the reverse proxy - href
strCalculated URL of the service before the reverse proxy - ip
strCalculated IP to contact the service
- domain
- displayOnHomepage
boolDisplay a link on homepage - reverseProxy
boolReached through the zone gateway reverse proxy (DNS points to the gateway LAN IP) - uniquePerZone
boolAt most one instance allowed per zone (generator validation) - externalAccess
boolwww-zone service reachable from the LAN via a fixed host IP (e.g. headscale, turn) - persist.dirs
listOf strService persistant dirs - persist.files
listOf strService persistant files - persist.dbDirs
listOf strService persistant dirs with database(s) - persist.dbFiles
listOf strService database file(s) - persist.varDirs
listOf strVariable secondary files (log, cache, etc.) - persist.mediaDirs
listOf strService media dirs (pictures, videos, big files) - proxy.enable
boolWhether to create virtualHost configuration (false for services that manage their own) - proxy.isProtected
boolOauth2 protected service - proxy.allowedGroups
listOf strKanidm groups allowed on this protected service (empty = any authenticated user) - proxy.isInternal
boolBind service on internal interface only (not internet accessible) - proxy.hasReverseProxy
boolThis is a reverse proxy (or another virtualhost configuration via extraConfig) - proxy.defaultService
boolIs the default service - proxy.servicePort
nullOr portService internal port - proxy.preExtraConfig
linesExtra caddy virtualHost configuration (prefix) - proxy.extraConfig
linesExtra caddy virtualHost configuration - proxy.extraGlobalConfig
linesExtra caddy configuration - proxy.scheme
strInternal service scheme (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 titled “⚙ darkone.system.sops”DNF sops, passwords and secrets management.
Wires sops-nix to usr/secrets/secrets.yaml and unlocks it with the
host SSH key (ssh_host_ed25519_key) plus the dedicated infrastructure
age key (/etc/sops/age/infra.key). Pre-declares a shared sops group,
the default-password / default-password-hash secrets (group-readable
by sops), and one user/<login>/password-hash secret per host user
(with neededForUsers = true so the hash is available before the user
accounts are created).
- enable
boolEnable sops automated configuration for DNF
darkone.system.sops.enable = false;⚙ darkone.system.srv-dirs
Section titled “⚙ darkone.system.srv-dirs”Shared directories management service.
- enable
boolEnable srv dirs, create the root dir (default /srv) - enableNfs
boolEnable nfs service paths (nfs/common, nfs/homes) - enableMedias
boolEnable media services paths (medias/[videos|music|incomming/…]) - root
strRoot dir for persistant data (/srv) - nfs
strNFS root directory (/srv/nfs) - homes
strDirectory for shared homes (/srv/nfs/homes) - common
strShared common directory (/srv/nfs/common linked to ~/Public) - medias
strMedias root dir (/srv/medias) - music
strShared music files directory (/srv/medias/music) - videos
strShared video files directory (/srv/medias/videos) - incoming
strShared incoming directory (/srv/medias/incoming write access) - incomingMusic
strShared incoming directory (/srv/medias/incoming/music write access) - incomingVideos
strShared incoming directory (/srv/medias/incoming/videos write access)
darkone.system.srv-dirs = { enable = cfg.enableNfs || cfg.enableMedias; enableNfs = false; enableMedias = false; root = "/srv"; nfs = null; homes = null; common = null; medias = null; music = null; videos = null; incoming = null; incomingMusic = null; incomingVideos = null;};⚙ darkone.system.testing
Section titled “⚙ darkone.system.testing”Standalone test mode for the NixOS Test Driver.
When enabled, neutralizes the irreducibly external/runtime bits so a node can be exercised in a VM: headscale/tailscale become no-ops and a fixed TLS cert can stub ACME. It also lets workDir-only config (nix.pub, harmonia.pub) be skipped by core/nix-cache. sops stays REAL (high fidelity).
- standalone
boolStandalone test mode — skip workDir-only config (nix.pub, harmonia.pub) and neutralize external services - tlsCert
nullOr pathSelf-signed cert (PEM) provided by the test harness to stub ACME. Never a tests/ path baked into the framework. - tlsKey
nullOr pathPrivate key (PEM) paired with tlsCert.
darkone.system.testing = { standalone = false; tlsCert = null; tlsKey = null;};⚙ darkone.system.yubikey
Section titled “⚙ darkone.system.yubikey”YubiKey strong authentication: fleet-wide PAM U2F + declarative FIDO2 LUKS.
One physical enrollment per (user, key) on the admin host — just yubikey <user> [key] [action] — feeds:
- a public registry
usr/secrets/yubikeys.jsonin the consumer workspace: pamu2fcfg credential, FIDO2 hmac-secret credential id and salt (all useless without the physical key, hence committable); - one sops secret
yubikey/<user>/<key>/luks-secret(the FIDO2-derived LUKS passphrase) plus the sharedluks-passphrase(the passphrase typed at disko install time, needed to authorize new keyslots).
The module then propagates everything declaratively (just apply), without
ever plugging the key on the target hosts:
- login / sudo / greeter: pam_u2f as a password alternative
(
sufficient): touching the key logs in, the sops password remains the automatic fallback. One credential is valid fleet-wide thanks to the fixed origin (pam://<network.domain>). - encrypted hosts: a oneshot service self-enrolls each declared key in
every disko-declared LUKS2 header (keyslot +
systemd-fido2token, the exact formatsystemd-cryptenrollwrites) and prunes revoked ones. The physical key is only ever needed at boot to unlock the disk.
- enable
boolYubiKey authentication (default: enabled when usr/secrets/yubikeys.json exists) - origin
strFixed pam_u2f origin/appid: one enrollment is valid fleet-wide - luks.enable
boolFIDO2 unlock of the host LUKS volumes (inert without disko LUKS + enrolled keys)
darkone.system.yubikey = { enable = hasRegistry; origin = "pam://${network.domain}"; luks.enable = true;};