summary refs log tree commit diff
diff options
context:
space:
mode:
authordatafoo <34766150+datafoo@users.noreply.github.com>2023-07-19 16:06:47 +0200
committerdatafoo <34766150+datafoo@users.noreply.github.com>2023-07-24 11:37:30 +0200
commit533ff8546ba1cab0072c846c588def683613eac8 (patch)
tree26453dece0c09ff20395a5bf2b18c22c5095b59f
parent874e84b69132c5be984bcc1e7a20b677f5e879c1 (diff)
downloadnixpkgs-533ff8546ba1cab0072c846c588def683613eac8.tar
nixpkgs-533ff8546ba1cab0072c846c588def683613eac8.tar.gz
nixpkgs-533ff8546ba1cab0072c846c588def683613eac8.tar.bz2
nixpkgs-533ff8546ba1cab0072c846c588def683613eac8.tar.lz
nixpkgs-533ff8546ba1cab0072c846c588def683613eac8.tar.xz
nixpkgs-533ff8546ba1cab0072c846c588def683613eac8.tar.zst
nixpkgs-533ff8546ba1cab0072c846c588def683613eac8.zip
nixos/mosquitto: leverage systemd credentials
Use systemd credentials for all variations of user passwords.
Password files do not need special permissions anymore.
-rw-r--r--nixos/modules/services/networking/mosquitto.nix65
1 files changed, 56 insertions, 9 deletions
diff --git a/nixos/modules/services/networking/mosquitto.nix b/nixos/modules/services/networking/mosquitto.nix
index a4fd2fd7c89..c53d86c0bab 100644
--- a/nixos/modules/services/networking/mosquitto.nix
+++ b/nixos/modules/services/networking/mosquitto.nix
@@ -42,12 +42,15 @@ let
       };
 
       passwordFile = mkOption {
-        type = uniq (nullOr types.path);
+        type = uniq (nullOr path);
         example = "/path/to/file";
         default = null;
         description = lib.mdDoc ''
           Specifies the path to a file containing the
           clear text password for the MQTT user.
+          The file is securely passed to mosquitto by
+          leveraging systemd credentials. No special
+          permissions need to be set on this file.
         '';
       };
 
@@ -64,7 +67,7 @@ let
       };
 
       hashedPasswordFile = mkOption {
-        type = uniq (nullOr types.path);
+        type = uniq (nullOr path);
         example = "/path/to/file";
         default = null;
         description = mdDoc ''
@@ -73,6 +76,9 @@ let
           To generate hashed password install the `mosquitto`
           package and use `mosquitto_passwd`, then remove the
           `username:` prefix from the generated file.
+          The file is securely passed to mosquitto by
+          leveraging systemd credentials. No special
+          permissions need to be set on this file.
         '';
       };
 
@@ -102,15 +108,43 @@ let
         message = "Cannot set more than one password option for user ${n} in ${prefix}";
       }) users;
 
-  makePasswordFile = users: path:
+  listenerScope = index: "listener-${toString index}";
+  userScope = prefix: index: "${prefix}-user-${toString index}";
+  credentialID = prefix: credential: "${prefix}-${credential}";
+
+  toScopedUsers = listenerScope: users: pipe users [
+    attrNames
+    (imap0 (index: user: nameValuePair user
+      (users.${user} // { scope = userScope listenerScope index; })
+    ))
+    listToAttrs
+  ];
+
+  userCredentials = user: credentials: pipe credentials [
+    (filter (credential: user.${credential} != null))
+    (map (credential: "${credentialID user.scope credential}:${user.${credential}}"))
+  ];
+  usersCredentials = listenerScope: users: credentials: pipe users [
+    (toScopedUsers listenerScope)
+    (mapAttrsToList (_: user: userCredentials user credentials))
+    concatLists
+  ];
+  systemdCredentials = listeners: listenerCredentials: pipe listeners [
+    (imap0 (index: listener: listenerCredentials (listenerScope index) listener))
+    concatLists
+  ];
+
+  makePasswordFile = listenerScope: users: path:
     let
-      makeLines = store: file:
+      makeLines = store: file: let
+        scopedUsers = toScopedUsers listenerScope users;
+      in
         mapAttrsToList
-          (n: u: "addLine ${escapeShellArg n} ${escapeShellArg u.${store}}")
-          (filterAttrs (_: u: u.${store} != null) users)
+          (name: user: ''addLine ${escapeShellArg name} "''$(systemd-creds cat ${credentialID user.scope store})"'')
+          (filterAttrs (_: user: user.${store} != null) scopedUsers)
         ++ mapAttrsToList
-          (n: u: "addFile ${escapeShellArg n} ${escapeShellArg "${u.${file}}"}")
-          (filterAttrs (_: u: u.${file} != null) users);
+          (name: user: ''addFile ${escapeShellArg name} "''${CREDENTIALS_DIRECTORY}/${credentialID user.scope file}"'')
+          (filterAttrs (_: user: user.${file} != null) scopedUsers);
       plainLines = makeLines "password" "passwordFile";
       hashedLines = makeLines "hashedPassword" "hashedPasswordFile";
     in
@@ -581,6 +615,19 @@ in
         ExecStart = "${cfg.package}/bin/mosquitto -c ${configFile}";
         ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
 
+        # Credentials
+        SetCredential = let
+          listenerCredentials = listenerScope: listener:
+            usersCredentials listenerScope listener.users [ "password" "hashedPassword" ];
+        in
+          systemdCredentials cfg.listeners listenerCredentials;
+
+        LoadCredential = let
+          listenerCredentials = listenerScope: listener:
+            usersCredentials listenerScope listener.users [ "passwordFile" "hashedPasswordFile" ];
+        in
+          systemdCredentials cfg.listeners listenerCredentials;
+
         # Hardening
         CapabilityBoundingSet = "";
         DevicePolicy = "closed";
@@ -653,7 +700,7 @@ in
         concatStringsSep
           "\n"
           (imap0
-            (idx: listener: makePasswordFile listener.users "${cfg.dataDir}/passwd-${toString idx}")
+            (idx: listener: makePasswordFile (listenerScope idx) listener.users "${cfg.dataDir}/passwd-${toString idx}")
             cfg.listeners);
     };