add clearer permissions
This commit is contained in:
parent
877560a974
commit
2eadf8918d
@ -3,18 +3,34 @@
|
|||||||
let
|
let
|
||||||
cfg = config.services.dufs;
|
cfg = config.services.dufs;
|
||||||
|
|
||||||
# Helper to create auth arguments from user list
|
# User credential submodule
|
||||||
# Each user needs a separate -a flag
|
userCredential = lib.types.submodule {
|
||||||
mkAuthArgs = users: readonlyUsers:
|
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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Helper to create auth arguments for different permission levels
|
||||||
|
mkAuthArgs = rwUsers: roUsers:
|
||||||
let
|
let
|
||||||
rwUsers = lib.concatMapStringsSep " "
|
writers = lib.concatMapStringsSep " "
|
||||||
(user: "-a '${user.username}:${user.passwordHash}@/:rw'")
|
(user: "-a '${user.username}:${user.passwordHash}@/:rw'")
|
||||||
users;
|
rwUsers;
|
||||||
roUsers = lib.concatMapStringsSep " "
|
readers = lib.concatMapStringsSep " "
|
||||||
(user: "-a '${user.username}:${user.passwordHash}@/:ro'")
|
(user: "-a '${user.username}:${user.passwordHash}@/:ro'")
|
||||||
readonlyUsers;
|
roUsers;
|
||||||
in
|
in
|
||||||
"${rwUsers} ${roUsers}";
|
lib.concatStringsSep " " (lib.filter (s: s != "") [writers readers]);
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.services.dufs = {
|
options.services.dufs = {
|
||||||
@ -65,6 +81,12 @@ in
|
|||||||
description = "Bind address for public instance";
|
description = "Bind address for public instance";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
users = lib.mkOption {
|
||||||
|
type = lib.types.listOf userCredential;
|
||||||
|
default = [];
|
||||||
|
description = "Users with read-write access";
|
||||||
|
};
|
||||||
|
|
||||||
allowSearch = lib.mkOption {
|
allowSearch = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
@ -88,55 +110,15 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
users = lib.mkOption {
|
users = lib.mkOption {
|
||||||
type = lib.types.listOf (lib.types.submodule {
|
type = lib.types.listOf userCredential;
|
||||||
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 = [];
|
default = [];
|
||||||
description = "List of users with read-write access";
|
description = "Users with read-write access";
|
||||||
example = [
|
|
||||||
{
|
|
||||||
username = "admin";
|
|
||||||
passwordHash = "$6$rounds=656000$...";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
readonlyUsers = lib.mkOption {
|
guestUsers = lib.mkOption {
|
||||||
type = lib.types.listOf (lib.types.submodule {
|
type = lib.types.listOf userCredential;
|
||||||
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 = [];
|
default = [];
|
||||||
description = "List of users with read-only access";
|
description = "Guest users with read-only access";
|
||||||
example = [
|
|
||||||
{
|
|
||||||
username = "viewer";
|
|
||||||
passwordHash = "$6$rounds=656000$...";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
allowUpload = lib.mkOption {
|
allowUpload = lib.mkOption {
|
||||||
@ -192,12 +174,18 @@ in
|
|||||||
Type = "simple";
|
Type = "simple";
|
||||||
User = cfg.user;
|
User = cfg.user;
|
||||||
Group = cfg.group;
|
Group = cfg.group;
|
||||||
ExecStart = ''
|
ExecStart =
|
||||||
${cfg.package}/bin/dufs ${cfg.servePathPublic} \
|
let
|
||||||
--bind ${cfg.publicInstance.bind} \
|
hasAuth = (cfg.publicInstance.users != []);
|
||||||
--port ${toString cfg.publicInstance.port} \
|
authArgs = lib.optionalString hasAuth
|
||||||
${lib.optionalString cfg.publicInstance.allowSearch "--allow-search"}
|
(mkAuthArgs cfg.publicInstance.users []) + " -a @/"; # allows read only on all paths (public)
|
||||||
'';
|
in ''
|
||||||
|
${cfg.package}/bin/dufs ${cfg.servePathPublic} \
|
||||||
|
--bind ${cfg.publicInstance.bind} \
|
||||||
|
--port ${toString cfg.publicInstance.port} \
|
||||||
|
${authArgs} \
|
||||||
|
${lib.optionalString cfg.publicInstance.allowSearch "--allow-search"}
|
||||||
|
'';
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
RestartSec = "10s";
|
RestartSec = "10s";
|
||||||
|
|
||||||
@ -224,7 +212,7 @@ in
|
|||||||
${cfg.package}/bin/dufs ${cfg.servePathPrivate} \
|
${cfg.package}/bin/dufs ${cfg.servePathPrivate} \
|
||||||
--bind ${cfg.privateInstance.bind} \
|
--bind ${cfg.privateInstance.bind} \
|
||||||
--port ${toString cfg.privateInstance.port} \
|
--port ${toString cfg.privateInstance.port} \
|
||||||
${mkAuthArgs cfg.privateInstance.users cfg.privateInstance.readonlyUsers} \
|
${mkAuthArgs cfg.privateInstance.users cfg.privateInstance.guestUsers} \
|
||||||
${lib.optionalString cfg.privateInstance.allowUpload "--allow-upload"} \
|
${lib.optionalString cfg.privateInstance.allowUpload "--allow-upload"} \
|
||||||
${lib.optionalString cfg.privateInstance.allowDelete "--allow-delete"} \
|
${lib.optionalString cfg.privateInstance.allowDelete "--allow-delete"} \
|
||||||
${lib.optionalString cfg.privateInstance.allowSearch "--allow-search"}
|
${lib.optionalString cfg.privateInstance.allowSearch "--allow-search"}
|
||||||
|
|||||||
@ -182,38 +182,37 @@ in
|
|||||||
user = "kage";
|
user = "kage";
|
||||||
group = "users";
|
group = "users";
|
||||||
|
|
||||||
# Public read-only instance
|
# Public instance with admin/guest authentication
|
||||||
publicInstance = {
|
publicInstance = {
|
||||||
enable = true;
|
enable = true;
|
||||||
port = 5000;
|
port = 5000;
|
||||||
allowSearch = true;
|
allowSearch = true;
|
||||||
|
# Admin users can upload/modify on public instance
|
||||||
|
users = [
|
||||||
|
{
|
||||||
|
username = "nate";
|
||||||
|
passwordHash = "$6$lJDBaW7zzlaAlzbV$u.mzsKCDOCWdUffPlXhx9dWRgJsxOUJRKj5Z5/NMEPC2WfPT9x9W145rThogzFLhynIT7UkYXd4zYdnsrGPRS0"; # open
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
# Private read-write instance with authentication
|
# Private instance with admin/user/guest authentication
|
||||||
privateInstance = {
|
privateInstance = {
|
||||||
enable = true;
|
enable = true;
|
||||||
port = 5001;
|
port = 5001;
|
||||||
allowUpload = true;
|
allowUpload = true;
|
||||||
allowDelete = true;
|
allowDelete = false;
|
||||||
allowSearch = true;
|
allowSearch = true;
|
||||||
# Read-write users
|
|
||||||
users = [
|
users = [
|
||||||
# Generate password hash with: mkpasswd -m sha-512
|
|
||||||
# These are temporary passwords and should be changed
|
|
||||||
{
|
{
|
||||||
username = "nate";
|
username = "user";
|
||||||
passwordHash = "$6$eIqVeCL9q5GlN.Em$xm7RxNcGfArYFBprmnggt1zzDf.HluKwXcG9LsJNCK6.vnKGmQDb5b7h7g81tWY7jIDdPsgLu0jiTzbz1lFIC0"; # password
|
passwordHash = "$6$lJDBaW7zzlaAlzbV$u.mzsKCDOCWdUffPlXhx9dWRgJsxOUJRKj5Z5/NMEPC2WfPT9x9W145rThogzFLhynIT7UkYXd4zYdnsrGPRS0"; # open
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
# Read-only users
|
guestUsers = [
|
||||||
readonlyUsers = [
|
|
||||||
{
|
{
|
||||||
username = "guest";
|
username = "guest";
|
||||||
passwordHash = "$6$.Ot.4AWNRpx0LJ1s$M01RpAJ.VZWJfDrTlali.P0Fhnn0Ji.uP/fIdgZP0ly64g8AzeGb6/2C9dbKmnARdVV9M12mLmU6ENmUbR/ym1"; # guest
|
passwordHash = "$6$.Ot.4AWNRpx0LJ1s$M01RpAJ.VZWJfDrTlali.P0Fhnn0Ji.uP/fIdgZP0ly64g8AzeGb6/2C9dbKmnARdVV9M12mLmU6ENmUbR/ym1"; # guest
|
||||||
}
|
|
||||||
{
|
|
||||||
username = "readonly";
|
|
||||||
passwordHash = "$6$3Z5KK8mIbxN2tZR4$eCOpbwAKAk6CKMZWgWddgJaQyTDUkYzB0T8tNXfSUQkUL2A/QEXoEONcPaZnF/jfem9qB..Snm2xR/7GTkyVg."; # readonly
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
@ -235,7 +234,6 @@ in
|
|||||||
listenAddresses = [ "*:631" ];
|
listenAddresses = [ "*:631" ];
|
||||||
allowFrom = [ "all" ];
|
allowFrom = [ "all" ];
|
||||||
browsing = true;
|
browsing = true;
|
||||||
# browserAddress = "192.168.1.169:631";
|
|
||||||
defaultShared = true;
|
defaultShared = true;
|
||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user