vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / networking / inadyn.nix
blobc98d6a2315061f59f4b9d1d119137c45e24e5e9a
1 { config, lib, pkgs, ... }:
2 let
3   cfg = config.services.inadyn;
5   # check if a value of an attrset is not null or an empty collection
6   nonEmptyValue = _: v: v != null && v != [ ] && v != { };
8   renderOption = k: v:
9     if builtins.elem k [ "provider" "custom" ] then
10       lib.concatStringsSep "\n"
11         (lib.mapAttrsToList
12           (name: config: ''
13             ${k} ${name} {
14                 ${lib.concatStringsSep "\n    " (lib.mapAttrsToList renderOption (lib.filterAttrs nonEmptyValue config))}
15             }'')
16           v)
17     else if k == "include" then
18       "${k}(\"${v}\")"
19     else if k == "hostname" && builtins.isList v then
20       "${k} = { ${builtins.concatStringsSep ", " (map (s: "\"${s}\"") v)} }"
21     else if builtins.isBool v then
22       "${k} = ${lib.boolToString v}"
23     else if builtins.isString v then
24       "${k} = \"${v}\""
25     else
26       "${k} = ${toString v}";
28   configFile' = pkgs.writeText "inadyn.conf"
29     ''
30       # This file was generated by nix
31       # do not edit
33       ${(lib.concatStringsSep "\n" (lib.mapAttrsToList renderOption (lib.filterAttrs nonEmptyValue cfg.settings)))}
34     '';
36   configFile = if (cfg.configFile != null) then cfg.configFile else configFile';
39   options.services.inadyn = with lib.types;
40     let
41       providerOptions =
42         {
43           include = lib.mkOption {
44             default = null;
45             description = "File to include additional settings for this provider from.";
46             type = nullOr path;
47           };
48           ssl = lib.mkOption {
49             default = true;
50             description = "Whether to use HTTPS for this DDNS provider.";
51             type = bool;
52           };
53           username = lib.mkOption {
54             default = null;
55             description = "Username for this DDNS provider.";
56             type = nullOr str;
57           };
58           password = lib.mkOption {
59             default = null;
60             description = ''
61               Password for this DDNS provider.
63               WARNING: This will be world-readable in the nix store.
64               To store credentials securely, use the `include` or `configFile` options.
65             '';
66             type = nullOr str;
67           };
68           hostname = lib.mkOption {
69             default = "*";
70             example = "your.cool-domain.com";
71             description = "Hostname alias(es).";
72             type = either str (listOf str);
73           };
74         };
75     in
76     {
77       enable = lib.mkEnableOption (''
78         synchronise your machine's IP address with a dynamic DNS provider using inadyn
79       '');
80       user = lib.mkOption {
81         default = "inadyn";
82         type = lib.types.str;
83         description = ''
84           User account under which inadyn runs.
86           ::: {.note}
87           If left as the default value this user will automatically be created
88           on system activation, otherwise you are responsible for
89           ensuring the user exists before the inadyn service starts.
90           :::
91         '';
92       };
93       group = lib.mkOption {
94         default = "inadyn";
95         type = lib.types.str;
96         description = ''
97           Group account under which inadyn runs.
99           ::: {.note}
100           If left as the default value this user will automatically be created
101           on system activation, otherwise you are responsible for
102           ensuring the user exists before the inadyn service starts.
103           :::
104         '';
105       };
106       interval = lib.mkOption {
107         default = "*-*-* *:*:00";
108         description = ''
109           How often to check the current IP.
110           Uses the format described in {manpage}`systemd.time(7)`";
111         '';
112         type = str;
113       };
114       logLevel = lib.mkOption {
115         type = lib.types.enum [ "none" "err" "warning" "info" "notice" "debug" ];
116         default = "notice";
117         description = "Set inadyn's log level.";
118       };
119       settings = lib.mkOption {
120         default = { };
121         description = "See `inadyn.conf (5)`";
122         type = submodule {
123           freeformType = attrs;
124           options = {
125             allow-ipv6 = lib.mkOption {
126               default = config.networking.enableIPv6;
127               defaultText = "`config.networking.enableIPv6`";
128               description = "Whether to get IPv6 addresses from interfaces.";
129               type = bool;
130             };
131             forced-update = lib.mkOption {
132               default = 2592000;
133               description = "Duration (in seconds) after which an update is forced.";
134               type = ints.positive;
135             };
136             provider = lib.mkOption {
137               default = { };
138               description = ''
139                 Settings for DDNS providers built-in to inadyn.
141                 For a list of built-in providers, see `inadyn.conf (5)`.
142               '';
143               type = attrsOf (submodule {
144                 freeformType = attrs;
145                 options = providerOptions;
146               });
147             };
148             custom = lib.mkOption {
149               default = { };
150               description = ''
151                 Settings for custom DNS providers.
152               '';
153               type = attrsOf (submodule {
154                 freeformType = attrs;
155                 options = providerOptions // {
156                   ddns-server = lib.mkOption {
157                     description = "DDNS server name.";
158                     type = str;
159                   };
160                   ddns-path = lib.mkOption {
161                     description = ''
162                       DDNS server path.
164                       See `inadnyn.conf (5)` for a list for format specifiers that can be used.
165                     '';
166                     example = "/update?user=%u&password=%p&domain=%h&myip=%i";
167                     type = str;
168                   };
169                 };
170               });
171             };
172           };
173         };
174       };
175       configFile = lib.mkOption {
176         default = null;
177         description = ''
178           Configuration file for inadyn.
180           Setting this will override all other configuration options.
182           Passed to the inadyn service using LoadCredential.
183         '';
184         type = nullOr path;
185       };
186     };
188   config = lib.mkIf cfg.enable {
189     systemd = {
190       services.inadyn = {
191         description = "Update nameservers using inadyn";
192         documentation = [
193           "man:inadyn"
194           "man:inadyn.conf"
195           "file:${pkgs.inadyn}/share/doc/inadyn/README.md"
196         ];
197         requires = [ "network-online.target" ];
198         wantedBy = [ "multi-user.target" ];
199         startAt = cfg.interval;
200         serviceConfig = {
201           Type = "oneshot";
202           ExecStart = ''${lib.getExe pkgs.inadyn} -f ${configFile} --cache-dir ''${CACHE_DIRECTORY} -1 --foreground -l ${cfg.logLevel}'';
203           LoadCredential = "config:${configFile}";
204           CacheDirectory = "inadyn";
206           User = cfg.user;
207           Group = cfg.group;
208           UMask = "0177";
209           LockPersonality = true;
210           MemoryDenyWriteExecute = true;
211           RestrictAddressFamilies = "AF_INET AF_INET6 AF_NETLINK";
212           NoNewPrivileges = true;
213           PrivateDevices = true;
214           PrivateTmp = true;
215           PrivateUsers = true;
216           ProtectSystem = "strict";
217           ProtectProc = "invisible";
218           ProtectHome = true;
219           ProtectClock = true;
220           ProtectControlGroups = true;
221           ProtectHostname = true;
222           ProtectKernelLogs = true;
223           ProtectKernelModules = true;
224           ProtectKernelTunables = true;
225           RestrictNamespaces = true;
226           RestrictRealtime = true;
227           RestrictSUIDSGID = true;
228           SystemCallArchitectures = "native";
229           SystemCallErrorNumber = "EPERM";
230           SystemCallFilter = "@system-service";
231           CapabilityBoundingSet = "";
232         };
233       };
235       timers.inadyn.timerConfig.Persistent = true;
236     };
238     users.users.inadyn = lib.mkIf (cfg.user == "inadyn") {
239       group = cfg.group;
240       isSystemUser = true;
241     };
243     users.groups = lib.mkIf (cfg.group == "inadyn") {
244       inadyn = { };
245     };
246   };