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