From fa01843a3b783cffaf0b7c8ca12a37e18ce2851c Mon Sep 17 00:00:00 2001 From: pinpox Date: Thu, 2 Jul 2026 21:42:30 +0200 Subject: [PATCH] nixos/yggdrasil: read private key from credentials dir The module bind-mounted the LoadCredential-provided key onto a /private-key target at the filesystem. systemd must create that target inode before overlaying the credential; the mount lives in the unit's namespace but the inode write hits the host filesystem, so a 0-byte /private-key file leaks onto the host and persists after the unit stops. Point PrivateKeyPath directly at the credential (/run/credentials/yggdrasil.service/private-key) and drop BindReadOnlyPaths. The DynamicUser can read the credentials dir, so the bind was never needed. Resolves #531972 Assisted-by: Oh My Pi (claude-opus-4-8) --- nixos/modules/services/networking/yggdrasil.nix | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/nixos/modules/services/networking/yggdrasil.nix b/nixos/modules/services/networking/yggdrasil.nix index d6331eeb3326..fe6c2e7eed5b 100644 --- a/nixos/modules/services/networking/yggdrasil.nix +++ b/nixos/modules/services/networking/yggdrasil.nix @@ -33,17 +33,11 @@ let else null; - # Build base configuration with systemd credential path override baseSettings = cfg.settings - // ( - if effectiveKeyPath != null then - { - PrivateKeyPath = "/private-key"; - } - else - { } - ); + // lib.optionalAttrs (effectiveKeyPath != null) { + PrivateKeyPath = "/run/credentials/yggdrasil.service/private-key"; + }; # Remove null values that yggdrasil doesn't expect cleanSettings = lib.filterAttrs (n: v: v != null) baseSettings; @@ -327,7 +321,6 @@ in StateDirectory = "yggdrasil"; RuntimeDirectory = "yggdrasil"; RuntimeDirectoryMode = "0750"; - BindReadOnlyPaths = lib.optional (effectiveKeyPath != null) "%d/private-key:/private-key"; LoadCredential = lib.optional (effectiveKeyPath != null) "private-key:${effectiveKeyPath}"; AmbientCapabilities = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE";