at 25.11-pre 4.6 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.services.webdav-server-rs; 9 format = pkgs.formats.toml { }; 10 settings = lib.recursiveUpdate { 11 server.uid = config.users.users."${cfg.user}".uid; 12 server.gid = config.users.groups."${cfg.group}".gid; 13 } cfg.settings; 14in 15{ 16 options = { 17 services.webdav-server-rs = { 18 enable = lib.mkEnableOption "WebDAV server"; 19 20 user = lib.mkOption { 21 type = lib.types.str; 22 default = "webdav"; 23 description = "User to run under when setuid is not enabled."; 24 }; 25 26 group = lib.mkOption { 27 type = lib.types.str; 28 default = "webdav"; 29 description = "Group to run under when setuid is not enabled."; 30 }; 31 32 debug = lib.mkOption { 33 type = lib.types.bool; 34 default = false; 35 description = "Enable debug mode."; 36 }; 37 38 settings = lib.mkOption { 39 type = format.type; 40 default = { }; 41 description = '' 42 Attrset that is converted and passed as config file. Available 43 options can be found at 44 [here](https://github.com/miquels/webdav-server-rs/blob/master/webdav-server.toml). 45 ''; 46 example = lib.literalExpression '' 47 { 48 server.listen = [ "0.0.0.0:4918" "[::]:4918" ]; 49 accounts = { 50 auth-type = "htpasswd.default"; 51 acct-type = "unix"; 52 }; 53 htpasswd.default = { 54 htpasswd = "/etc/htpasswd"; 55 }; 56 location = [ 57 { 58 route = [ "/public/*path" ]; 59 directory = "/srv/public"; 60 handler = "filesystem"; 61 methods = [ "webdav-ro" ]; 62 autoindex = true; 63 auth = "false"; 64 } 65 { 66 route = [ "/user/:user/*path" ]; 67 directory = "~"; 68 handler = "filesystem"; 69 methods = [ "webdav-rw" ]; 70 autoindex = true; 71 auth = "true"; 72 setuid = true; 73 } 74 ]; 75 } 76 ''; 77 }; 78 79 configFile = lib.mkOption { 80 type = lib.types.path; 81 default = format.generate "webdav-server.toml" settings; 82 defaultText = "Config file generated from services.webdav-server-rs.settings"; 83 description = '' 84 Path to config file. If this option is set, it will override any 85 configuration done in services.webdav-server-rs.settings. 86 ''; 87 example = "/etc/webdav-server.toml"; 88 }; 89 }; 90 }; 91 92 config = lib.mkIf cfg.enable { 93 assertions = [ 94 { 95 assertion = lib.hasAttr cfg.user config.users.users && config.users.users."${cfg.user}".uid != null; 96 message = "users.users.${cfg.user} and users.users.${cfg.user}.uid must be defined."; 97 } 98 { 99 assertion = 100 lib.hasAttr cfg.group config.users.groups && config.users.groups."${cfg.group}".gid != null; 101 message = "users.groups.${cfg.group} and users.groups.${cfg.group}.gid must be defined."; 102 } 103 ]; 104 105 users.users = lib.optionalAttrs (cfg.user == "webdav") { 106 webdav = { 107 description = "WebDAV user"; 108 group = cfg.group; 109 uid = config.ids.uids.webdav; 110 }; 111 }; 112 113 users.groups = lib.optionalAttrs (cfg.group == "webdav") { 114 webdav.gid = config.ids.gids.webdav; 115 }; 116 117 systemd.services.webdav-server-rs = { 118 description = "WebDAV server"; 119 after = [ "network.target" ]; 120 wantedBy = [ "multi-user.target" ]; 121 serviceConfig = { 122 ExecStart = "${pkgs.webdav-server-rs}/bin/webdav-server ${lib.optionalString cfg.debug "--debug"} -c ${cfg.configFile}"; 123 124 CapabilityBoundingSet = [ 125 "CAP_SETUID" 126 "CAP_SETGID" 127 ]; 128 129 NoExecPaths = [ "/" ]; 130 ExecPaths = [ "/nix/store" ]; 131 132 # This program actively detects if it is running in root user account 133 # when it starts and uses root privilege to switch process uid to 134 # respective unix user when a user logs in. Maybe we can enable 135 # DynamicUser in the future when it's able to detect CAP_SETUID and 136 # CAP_SETGID capabilities. 137 138 NoNewPrivileges = true; 139 PrivateDevices = true; 140 PrivateTmp = true; 141 ProtectClock = true; 142 ProtectControlGroups = true; 143 ProtectKernelLogs = true; 144 ProtectKernelModules = true; 145 ProtectKernelTunables = true; 146 ProtectSystem = true; 147 }; 148 }; 149 }; 150 151 meta.maintainers = with lib.maintainers; [ pmy ]; 152}