1 { config, lib, pkgs, ... }:
6 cfg = config.services.samba-wsdd;
10 services.samba-wsdd = {
11 enable = mkEnableOption (lib.mdDoc ''
12 Web Services Dynamic Discovery host daemon. This enables (Samba) hosts, like your local NAS device,
13 to be found by Web Service Discovery Clients like Windows.
15 interface = mkOption {
16 type = types.nullOr types.str;
19 description = lib.mdDoc "Interface or address to use.";
22 type = types.nullOr types.int;
25 description = lib.mdDoc "Hop limit for multicast packets (default = 1).";
27 openFirewall = mkOption {
28 description = lib.mdDoc ''
29 Whether to open the required firewall ports in the firewall.
32 type = lib.types.bool;
34 workgroup = mkOption {
35 type = types.nullOr types.str;
38 description = lib.mdDoc "Set workgroup name (default WORKGROUP).";
41 type = types.nullOr types.str;
43 example = "FILESERVER";
44 description = lib.mdDoc "Override (NetBIOS) hostname to be used (default hostname).";
47 type = types.nullOr types.str;
49 description = lib.mdDoc "Set domain name (disables workgroup).";
51 discovery = mkOption {
54 description = lib.mdDoc "Enable discovery operation mode.";
58 default = "/run/wsdd/wsdd.sock";
59 description = lib.mdDoc "Listen on path or localhost port in discovery mode.";
61 extraOptions = mkOption {
62 type = types.listOf types.str;
63 default = [ "--shortlog" ];
64 example = [ "--verbose" "--no-http" "--ipv4only" "--no-host" ];
65 description = lib.mdDoc "Additional wsdd options.";
70 config = mkIf cfg.enable {
72 environment.systemPackages = [ pkgs.wsdd ];
74 systemd.services.samba-wsdd = {
75 description = "Web Services Dynamic Discovery host daemon";
76 after = [ "network.target" ];
77 wantedBy = [ "multi-user.target" ];
82 ${pkgs.wsdd}/bin/wsdd ${optionalString (cfg.interface != null) "--interface '${cfg.interface}'"} \
83 ${optionalString (cfg.hoplimit != null) "--hoplimit '${toString cfg.hoplimit}'"} \
84 ${optionalString (cfg.workgroup != null) "--workgroup '${cfg.workgroup}'"} \
85 ${optionalString (cfg.hostname != null) "--hostname '${cfg.hostname}'"} \
86 ${optionalString (cfg.domain != null) "--domain '${cfg.domain}'"} \
87 ${optionalString cfg.discovery "--discovery --listen '${cfg.listen}'"} \
88 ${escapeShellArgs cfg.extraOptions}
90 # Runtime directory and mode
91 RuntimeDirectory = "wsdd";
92 RuntimeDirectoryMode = "0750";
93 # Access write directories
96 CapabilityBoundingSet = "";
98 NoNewPrivileges = true;
100 ProtectSystem = "strict";
103 PrivateDevices = true;
104 PrivateUsers = false;
105 ProtectHostname = true;
107 ProtectKernelTunables = true;
108 ProtectKernelModules = true;
109 ProtectKernelLogs = true;
110 ProtectControlGroups = true;
111 RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK" ];
112 RestrictNamespaces = true;
113 LockPersonality = true;
114 MemoryDenyWriteExecute = true;
115 RestrictRealtime = true;
116 RestrictSUIDSGID = true;
117 PrivateMounts = true;
118 # System Call Filtering
119 SystemCallArchitectures = "native";
120 SystemCallFilter = "~@cpu-emulation @debug @mount @obsolete @privileged @resources";
124 networking.firewall = mkIf cfg.openFirewall {
125 allowedTCPPorts = [ 5357 ];
126 allowedUDPPorts = [ 3702 ];