1 { config, lib, pkgs, ... }:
3 cfg = config.services.samba-wsdd;
7 services.samba-wsdd = {
8 enable = lib.mkEnableOption ''
9 Web Services Dynamic Discovery host daemon. This enables (Samba) hosts, like your local NAS device,
10 to be found by Web Service Discovery Clients like Windows
12 interface = lib.mkOption {
13 type = lib.types.nullOr lib.types.str;
16 description = "Interface or address to use.";
18 hoplimit = lib.mkOption {
19 type = lib.types.nullOr lib.types.int;
22 description = "Hop limit for multicast packets (default = 1).";
24 openFirewall = lib.mkOption {
26 Whether to open the required firewall ports in the firewall.
29 type = lib.types.bool;
31 workgroup = lib.mkOption {
32 type = lib.types.nullOr lib.types.str;
35 description = "Set workgroup name (default WORKGROUP).";
37 hostname = lib.mkOption {
38 type = lib.types.nullOr lib.types.str;
40 example = "FILESERVER";
41 description = "Override (NetBIOS) hostname to be used (default hostname).";
43 domain = lib.mkOption {
44 type = lib.types.nullOr lib.types.str;
46 description = "Set domain name (disables workgroup).";
48 discovery = lib.mkOption {
49 type = lib.types.bool;
51 description = "Enable discovery operation mode.";
53 listen = lib.mkOption {
55 default = "/run/wsdd/wsdd.sock";
56 description = "Listen on path or localhost port in discovery mode.";
58 extraOptions = lib.mkOption {
59 type = lib.types.listOf lib.types.str;
60 default = [ "--shortlog" ];
61 example = [ "--verbose" "--no-http" "--ipv4only" "--no-host" ];
62 description = "Additional wsdd options.";
67 config = lib.mkIf cfg.enable {
69 environment.systemPackages = [ pkgs.wsdd ];
71 systemd.services.samba-wsdd = {
72 description = "Web Services Dynamic Discovery host daemon";
73 after = [ "network.target" ];
74 wantedBy = [ "multi-user.target" ];
79 ${pkgs.wsdd}/bin/wsdd ${lib.optionalString (cfg.interface != null) "--interface '${cfg.interface}'"} \
80 ${lib.optionalString (cfg.hoplimit != null) "--hoplimit '${toString cfg.hoplimit}'"} \
81 ${lib.optionalString (cfg.workgroup != null) "--workgroup '${cfg.workgroup}'"} \
82 ${lib.optionalString (cfg.hostname != null) "--hostname '${cfg.hostname}'"} \
83 ${lib.optionalString (cfg.domain != null) "--domain '${cfg.domain}'"} \
84 ${lib.optionalString cfg.discovery "--discovery --listen '${cfg.listen}'"} \
85 ${lib.escapeShellArgs cfg.extraOptions}
87 # Runtime directory and mode
88 RuntimeDirectory = "wsdd";
89 RuntimeDirectoryMode = "0750";
90 # Access write directories
93 CapabilityBoundingSet = "";
95 NoNewPrivileges = true;
97 ProtectSystem = "strict";
100 PrivateDevices = true;
101 PrivateUsers = false;
102 ProtectHostname = true;
104 ProtectKernelTunables = true;
105 ProtectKernelModules = true;
106 ProtectKernelLogs = true;
107 ProtectControlGroups = true;
108 RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK" ];
109 RestrictNamespaces = true;
110 LockPersonality = true;
111 MemoryDenyWriteExecute = true;
112 RestrictRealtime = true;
113 RestrictSUIDSGID = true;
114 PrivateMounts = true;
115 # System Call Filtering
116 SystemCallArchitectures = "native";
117 SystemCallFilter = "~@cpu-emulation @debug @mount @obsolete @privileged @resources";
121 networking.firewall = lib.mkIf cfg.openFirewall {
122 allowedTCPPorts = [ 5357 ];
123 allowedUDPPorts = [ 3702 ];