Security modules
π darkone.security.complement
Section titled βπ darkone.security.complementβCross-cutting complementary measures β Annex A (C1βC12). (wip)
These measures have no ANSSI number but are essential to the guideβs spirit. Covers linux-hardened patches (C1), Lockdown LSM (C2), USBGuard (C3), nftables deny-by-default (C4), hardened SSH (C5), LUKS2 (C6), NTP/NTS (C7), secure DNS (C8), disabled core dumps (C9), PAM anti brute-force (C10), legal banners (C11), and cron/at restriction (C12).
- enable
boolEnable complementary ANSSI measures (C1βC12). - lockdownLevel
enum [ "none" "integrity" "confidentiality" ]Lockdown LSM level (C2) - lsmStack
listOf strLSM stack order (C2, R11, R20). Modifies boot.kernelParams lsm=β¦ - ntpServers
listOf strNTP/NTS servers (C7). - useNts
boolEnable NTS (Network Time Security) for NTP authentication (C7). - sshBanner
strSSH banner displayed before authentication (C11). - cronAllowedUsers
listOf strUsers allowed to schedule cron jobs (C12). - atAllowedUsers
listOf strUsers allowed to schedule at jobs (C12). Mirrors cronAllowedUsers by default. - egressAllowlist
listOf strIPv4/IPv6 addresses or CIDRs allowed outbound under the C4 reinforced egress deny-by-default policy. Empty list keeps the policy but only loopback and established/related traffic pass (proxy required).
darkone.security.complement = { enable = false; lockdownLevel = "integrity"; lsmStack = [ ]; ntpServers = [ ]; useNts = true; sshBanner = '' βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β DNF NETWORK NODE β β Restricted and monitored access. β β Unauthorized access may result in criminal prosecution β β under Articles 323-1 to 323-8 of the French Penal Code. β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ''; cronAllowedUsers = [ ]; atAllowedUsers = [ ]; egressAllowlist = [ ];};π darkone.security.filesystem
Section titled βπ darkone.security.filesystemβPartitioning, file tree, and file permissions (R28βR29, R50βR57). (wip)
Covers secure mount options (R28), restriction of /boot (R29), permissions of sensitive files (R50), passwords kept out of the store (R51), sockets (R52), orphan files (R53), sticky bit (R54), per-user temporary directories (R55), and setuid (R56, R57).
- enable
boolEnable ANSSI filesystem hardening (R28βR29, R50βR57). - allowedSetuid
listOf strAllowlist of tolerated setuid/setgid binaries (R56, R57). - tmpfs
boolWhether R28 owns/tmpas a hardened tmpfs sized onboot.tmp.tmpfsSize. Set tofalseto leave/tmpon the filesystem it already lives on β a host keeping several GB of persistent scratch there loses both the data and the RAM otherwise. - tmpNoexec
boolWhether the R28/tmpcarriesnoexec.noexecblocks direct execution anddlopen, so it breaks any runtime unpacking native libraries there (Bun, Electron, agent tooling) and anything compiling then running inTMPDIR. Only meaningful whentmpfsistrue. - extraMountHardening
listOf strMount points to harden withnosuid,nodev,noexec(R28). Each listed path MUST be a separate partition declared elsewhere (hardware- configuration / disko); the options are merged into its existingfileSystemsentry. An explicit list (rather than a global flag) avoids guessing the layout and never creates phantom mounts. Do not list/homeif users run scripts there βnoexecwould break them.
darkone.security.filesystem = { enable = false; allowedSetuid = [ ]; tmpfs = true; tmpNoexec = true; extraMountHardening = [ ];};π darkone.security.integrity
Section titled βπ darkone.security.integrityβFilesystem integrity β HIDS (R76βR77). (wip)
Covers sealing and integrity verification via AIDE (R76) and protection of the sealed database with GPG signature plus remote copy (R77).
- enable
boolEnable ANSSI HIDS integrity β AIDE (R76βR77). - aideRemoteCopy
nullOr submoduleRemote copy of the GPG-signed AIDE database (R77). null = disabled.- host
strRemote host for the AIDE database copy. - sshKeyFile
pathPath to the private SSH key for the remote copy.
- host
darkone.security.integrity = { enable = false; aideRemoteCopy = null; aideRemoteCopy.host = null; aideRemoteCopy.sshKeyFile = null;};π darkone.security.journaling
Section titled βπ darkone.security.journalingβLogging and auditd (R71βR73). (wip)
Covers persistent logging with TLS forwarding (R71), per-service dedicated journals (R72), and auditd with ANSSI rules (R73).
- enable
boolEnable ANSSI logging and auditd (R71βR73).
darkone.security.journaling.enable = false;π darkone.security.kernel-build
Section titled βπ darkone.security.kernel-buildβStatic kernel configuration β requires recompilation (R15βR27). (wip)
These rules require a custom kernel via boot.kernelPackages.
NixOS allows this through structuredExtraConfig. All these rules carry
the kernel-recompile tag: they are skipped if that tag is in excludes.
- enable
boolEnable the ANSSI kernel recompilation module (R15βR27).
darkone.security.kernel-build.enable = false;π darkone.security.kernel-params
Section titled βπ darkone.security.kernel-paramsβDynamic kernel configuration: boot parameters and sysctls (R8βR14). (wip)
Rules applicable without recompiling the kernel. Covers memory options (R8), system sysctls (R9), disabling module loading (R10), Yama/ptrace (R11), IPv4 network sysctls (R12), IPv6 disabling (R13), and filesystem sysctls (R14).
- enable
boolEnable ANSSI dynamic kernel parameters (R8βR14). - restrictUserns
boolR9: forbid unprivileged user namespaces (user.max_user_namespaces). Breaks Flatpak, bubblewrap and rootless Podman, so it stays opt-in and belongs on servers that run none of them. - disableSmt
boolR8: turn hyperthreading off. Three parameters carry it;falsefalls each back to its SMT-preserving form and leaves the other fourteen alone. Notel1tf=fulldrops SMT even withoutforceβ it only leaves the sysfs knob behind β so the fallback there isflush. - memoryDebug
boolR8: the allocator extras βslub_debug=FZP,page_poison=onandslab_nomerge=yes. None of the three is in the ANSSI R8 list, andpage_poisondisplacesinit_on_alloc/init_on_free, which are: the kernel says so at boot, and honours the debug facility instead. Turning it off restores the specified wipe and gives back 7% of a compile (95s to 88s, ms-a2, SMT on). - disableIpv6
boolR13: disable IPv6 entirely. Off by default β ANSSI itself prefers hardening IPv6 over dropping it, and a public host generally needs it.
darkone.security.kernel-params = { enable = false; restrictUserns = false; disableSmt = true; memoryDebug = true; disableIpv6 = false;};π darkone.security.mac
Section titled βπ darkone.security.macβMandatory Access Control β MAC (R37, R45βR49). (wip)
R37 is a meta rule: valid if at least R45 (AppArmor) or R46 (SELinux)
is active. SELinux (R46βR49) is not supported on NixOS and is excluded
by default via exceptions. AppArmor (R45) is partially supported.
- enable
boolEnable ANSSI MAC module β AppArmor/SELinux (R37, R45βR49).
darkone.security.mac.enable = false;π darkone.security.mta
Section titled βπ darkone.security.mtaβLocal mail handling (R74βR75). (wip)
Covers the local MTA hardened to loopback-only (R74) and mail aliases routed to the administratorβs address (R75). These rules only apply if an MTA service is active (Postfix or OpenSMTPD).
- enable
boolEnable ANSSI MTA hardening (R74βR75).
darkone.security.mta.enable = false;π darkone.security.network
Section titled βπ darkone.security.networkβNetwork services β isolation and supervision (R78βR80). (wip)
Covers isolation of network services (R78: server category), hardening and monitoring of exposed services (R79: fail2ban, HTTP headers, ANSSI TLS) and reduction of the network surface (R80).
- enable
boolEnable ANSSI network hardening (R78βR80). - exposedServices
listOf strPublic services to jail with fail2ban (R79). Each entry MUST resolve to a filter β one shipped by fail2ban, or one declared infiltersβ or the assertion refuses the build. - filters
attrsFilters usable inexposedServices, on top of those fail2ban ships. Caddy, Synapse and Kanidm need theirs written against real journal output β declare them here once the patterns are confirmed.- journalmatch
strJournal match for the jail (fail2ban runs on the systemd backend). - failregex
strFailure pattern, written tofilter.d/<name>.conf. Empty when fail2ban already ships the filter and only the match is missing.
- journalmatch
- publicListeners
listOf strServices allowed to listen on 0.0.0.0 / :: (R80). - httpsHeaders
boolAdds ANSSI HTTP security headers in Nginx/Caddy (R79). - tlsCiphers
listOf strANSSI TLS cipher suite for Nginx (R79).
darkone.security.network = { enable = false; exposedServices = [ ]; filters.journalmatch = "_SYSTEMD_UNIT=forgejo.service"; filters.failregex = ""; publicListeners = [ ]; httpsHeaders = true; tlsCiphers = [ ];};π darkone.security.nss
Section titled βπ darkone.security.nssβNSS β Remote user databases (R69βR70). (wip)
Rules applicable only if an external NSS is active (SSSD, nslcd). Not currently relevant for DNF; see what can be done with Kanidm + PAM.
Covers hardening of remote databases (R69: TLS mandatory) and separation of system and directory accounts (R70).
- enable
boolEnable ANSSI NSS hardening (R69βR70).
darkone.security.nss.enable = false;π darkone.security.packages
Section titled βπ darkone.security.packagesβPackage management and updates (R58βR61). (wip)
Covers installing only what is strictly necessary (R58), trusted repositories (R59), hardened repositories (R60: linux_hardened), and regular updates (R61).
- enable
boolEnable ANSSI package management (R58βR61). - trustedSubstituters
listOf strAllowlist of authorized Nix binary caches (R59). - trustedPublicKeys
listOf strPublic keys for authorized binary caches (R59). - allowedUris
listOf strPrefix allowlist of URIs fetchable during evaluation (R59). Restricts builtins.fetch* / flake inputs to internal mirrors. Empty list disables the restriction. - maxSystemPackages
nullOr intSoft threshold on the number of system packages (R58). Emits an evaluation warning when exceeded; null disables the check.
darkone.security.packages = { enable = false; trustedSubstituters = [ ]; trustedPublicKeys = [ ]; allowedUris = [ ]; maxSystemPackages = 200;};π darkone.security.pam
Section titled βπ darkone.security.pamβPAM β Authentication and password storage (R67βR68). (wip)
Covers secure remote PAM authentication (R67: SSSD, Kerberos, pam_faillock) and encrypted password storage (R68: yescrypt).
- enable
boolEnable ANSSI PAM module β authentication and passwords (R67βR68). - faillock.deny
ints.positiveFailed attempts before pam_faillock locks the account (R67). - faillock.unlockTime
ints.positiveSeconds an account stays locked (R67). Unlock early withfaillock --reset.
darkone.security.pam = { enable = false; faillock.deny = 3; faillock.unlockTime = 900;};π darkone.security.preboot
Section titled βπ darkone.security.prebootβHardware configuration and secure boot (R1βR7). (wip)
Covers UEFI Secure Boot (R3), lanzaboote, bootloader password (R5), signed UKIs (R6), and IOMMU (R7). R1 and R2 (hardware/firmware) are out of NixOS scope and only produce a note in the report.
- enable
boolEnable ANSSI secure boot β Secure Boot, IOMMU (R1βR7).
darkone.security.preboot.enable = false;π darkone.security.services
Section titled βπ darkone.security.servicesβHardening of systemd services (R62βR66). (wip)
Covers disabling unnecessary services (R62), reducing functionality via systemd security options (R63), privilege restriction (R64), isolation (R65), and hardening of containerization components (R66).
- enable
boolEnable ANSSI hardening of systemd services (R62βR66). - rootServicesAllowed
listOf strsystemd services allowed to run as root without CapabilityBoundingSet (R64). - hardenedUnits
listOf strsystemd units to which the ANSSI hardening baseline is applied (R52 RuntimeDirectoryMode, R55 PrivateTmp, R63 full sandbox viadnfLib.mkHardenedServiceConfig). Empty by default: blanket sandboxing can break services that need write access or extra syscalls, so units are opt-in. List framework-owned units known to tolerate confinement; per-unitserviceConfigoverrides still win.
darkone.security.services = { enable = false; rootServicesAllowed = [ ]; hardenedUnits = [ ];};π darkone.security.sudo
Section titled βπ darkone.security.sudoβsudo hardening (R38βR44). (wip)
Covers the dedicated sudo group (R38), hardened sudo directives (R39), restriction of non-root targets (R40), NOEXEC limitation (R41), forbidding negations (R42), explicit argument specification (R43), and use of sudoedit (R44).
- enable
boolEnable ANSSI sudo hardening (R38βR44). - allowedRootRules
listOf strsudo rules allowed to target root (R40). Others must target a service account.
darkone.security.sudo = { enable = false; allowedRootRules = [ ];};π darkone.security.users
Section titled βπ darkone.security.usersβUser accounts and authentication (R30βR36). (wip)
Covers unused accounts (R30), password policy (R31), inactivity locking (R32), admin accountability (R33), service accounts (R34), unique service accounts (R35), and umask (R36).
- enable
boolEnable ANSSI account management (R30βR36). - idleTimeout
ints.unsignedSeconds before an idle login shell exits (R32,TMOUT).0drops the TTY timeout entirely; the GNOME idle lock is unaffected. Workstations holding long-lived terminals (build farm, agent tooling) set0.
darkone.security.users = { enable = false; idleTimeout = 600;};