diff --git a/shared/modules/services/dufs.nix b/shared/modules/services/dufs.nix index 182c6e7..532e353 100644 --- a/shared/modules/services/dufs.nix +++ b/shared/modules/services/dufs.nix @@ -3,10 +3,18 @@ let cfg = config.services.dufs; - # Helper to create auth string from user list - mkAuthString = users: lib.concatMapStringsSep "|" - (user: "${user.username}:${user.passwordHash}@/:rw") - users; + # Helper to create auth arguments from user list + # Each user needs a separate -a flag + mkAuthArgs = users: readonlyUsers: + let + rwUsers = lib.concatMapStringsSep " " + (user: "-a '${user.username}:${user.passwordHash}@/:rw'") + users; + roUsers = lib.concatMapStringsSep " " + (user: "-a '${user.username}:${user.passwordHash}@/:ro'") + readonlyUsers; + in + "${rwUsers} ${roUsers}"; in { options.services.dufs = { @@ -88,7 +96,10 @@ in }; passwordHash = lib.mkOption { type = lib.types.str; - description = "SHA-512 password hash (generate with: openssl passwd -6)"; + description = '' + SHA-512 password hash (generate with: mkpasswd -m sha-512) + Note: Must start with $6$ for dufs compatibility + ''; }; }; }); @@ -102,6 +113,32 @@ in ]; }; + readonlyUsers = lib.mkOption { + type = lib.types.listOf (lib.types.submodule { + options = { + username = lib.mkOption { + type = lib.types.str; + description = "Username for authentication"; + }; + passwordHash = lib.mkOption { + type = lib.types.str; + description = '' + SHA-512 password hash (generate with: mkpasswd -m sha-512) + Note: Must start with $6$ for dufs compatibility + ''; + }; + }; + }); + default = []; + description = "List of users with read-only access"; + example = [ + { + username = "viewer"; + passwordHash = "$6$rounds=656000$..."; + } + ]; + }; + allowUpload = lib.mkOption { type = lib.types.bool; default = true; @@ -139,6 +176,12 @@ in users.groups.${cfg.group} = {}; + # Ensure proper ownership of dufs directories + systemd.tmpfiles.rules = [ + "d ${cfg.servePathPublic} 0755 ${cfg.user} ${cfg.group} -" + "d ${cfg.servePathPrivate} 0755 ${cfg.user} ${cfg.group} -" + ]; + # Public read-only instance systemd.services.dufs-public = lib.mkIf cfg.publicInstance.enable { description = "dufs public read-only file server"; @@ -182,7 +225,7 @@ in ${cfg.package}/bin/dufs ${cfg.servePathPrivate} \ --bind ${cfg.privateInstance.bind} \ --port ${toString cfg.privateInstance.port} \ - --auth '${mkAuthString cfg.privateInstance.users}' \ + ${mkAuthArgs cfg.privateInstance.users cfg.privateInstance.readonlyUsers} \ ${lib.optionalString cfg.privateInstance.allowUpload "--allow-upload"} \ ${lib.optionalString cfg.privateInstance.allowDelete "--allow-delete"} \ ${lib.optionalString cfg.privateInstance.allowSearch "--allow-search"} \ diff --git a/shared/server-configuration.nix b/shared/server-configuration.nix index 9e405ec..5ad2c64 100644 --- a/shared/server-configuration.nix +++ b/shared/server-configuration.nix @@ -194,20 +194,24 @@ in allowUpload = true; allowDelete = true; allowSearch = true; + # Read-write users users = [ - # Generate password hash with: openssl passwd -6 - # Replace with actual username and hash - # { - # username = "admin"; - # passwordHash = "$6$rounds=656000$..."; - # } + # Generate password hash with: mkpasswd -m sha-512 + # These are temporary passwords and should be changed { username = "nate"; - passwordHash = "$6$rounds=656000$6$3.mottgY50yEZJlr$8a8ztrB/G2kZ39C0cAMDEfQGd93sqL4tS.gQKjnDrRQVvE.VTIlp5JF/GRW95YsKhaOF3r9ui9RTj88Z8LBV80"; + passwordHash = "$6$eIqVeCL9q5GlN.Em$xm7RxNcGfArYFBprmnggt1zzDf.HluKwXcG9LsJNCK6.vnKGmQDb5b7h7g81tWY7jIDdPsgLu0jiTzbz1lFIC0"; # password } + ]; + # Read-only users + readonlyUsers = [ { username = "guest"; - passwordHash = "$6$rounds=656000$6$tJlnxZhnNFPaDEXf$0Q.wZwDczaLfk5rIvX6FfCYvS75IY16WpuXKJyRMbdq4Ie8mZC3fSp5oOB95bMDRHRcabexi5Fp8j39c0pYc8."; + passwordHash = "$6$.Ot.4AWNRpx0LJ1s$M01RpAJ.VZWJfDrTlali.P0Fhnn0Ji.uP/fIdgZP0ly64g8AzeGb6/2C9dbKmnARdVV9M12mLmU6ENmUbR/ym1"; # guest + } + { + username = "readonly"; + passwordHash = "$6$3Z5KK8mIbxN2tZR4$eCOpbwAKAk6CKMZWgWddgJaQyTDUkYzB0T8tNXfSUQkUL2A/QEXoEONcPaZnF/jfem9qB..Snm2xR/7GTkyVg."; # readonly } ]; };