vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / networking / ddclient.nix
blobda76ff5153d6c8fe0f53a912cf978e3234957161
1 { config, pkgs, lib, ... }:
2 let
3   cfg = config.services.ddclient;
4   boolToStr = bool: if bool then "yes" else "no";
5   dataDir = "/var/lib/ddclient";
6   StateDirectory = builtins.baseNameOf dataDir;
7   RuntimeDirectory = StateDirectory;
9   configFile' = pkgs.writeText "ddclient.conf" ''
10     # This file can be used as a template for configFile or is automatically generated by Nix options.
11     cache=${dataDir}/ddclient.cache
12     foreground=YES
13     ${lib.optionalString (cfg.use != "") "use=${cfg.use}"}
14     ${lib.optionalString (cfg.use == "" && cfg.usev4 != "") "usev4=${cfg.usev4}"}
15     ${lib.optionalString (cfg.use == "" && cfg.usev6 != "") "usev6=${cfg.usev6}"}
16     login=${cfg.username}
17     password=${if cfg.protocol == "nsupdate" then "/run/${RuntimeDirectory}/ddclient.key" else "@password_placeholder@"}
18     protocol=${cfg.protocol}
19     ${lib.optionalString (cfg.script != "") "script=${cfg.script}"}
20     ${lib.optionalString (cfg.server != "") "server=${cfg.server}"}
21     ${lib.optionalString (cfg.zone != "")   "zone=${cfg.zone}"}
22     ssl=${boolToStr cfg.ssl}
23     wildcard=YES
24     quiet=${boolToStr cfg.quiet}
25     verbose=${boolToStr cfg.verbose}
26     ${cfg.extraConfig}
27     ${lib.concatStringsSep "," cfg.domains}
28   '';
29   configFile = if (cfg.configFile != null) then cfg.configFile else configFile';
31   preStart = ''
32     install --mode=600 --owner=$USER ${configFile} /run/${RuntimeDirectory}/ddclient.conf
33     ${lib.optionalString (cfg.configFile == null) (if (cfg.protocol == "nsupdate") then ''
34       install --mode=600 --owner=$USER ${cfg.passwordFile} /run/${RuntimeDirectory}/ddclient.key
35     '' else if (cfg.passwordFile != null) then ''
36       "${pkgs.replace-secret}/bin/replace-secret" "@password_placeholder@" "${cfg.passwordFile}" "/run/${RuntimeDirectory}/ddclient.conf"
37     '' else ''
38       sed -i '/^password=@password_placeholder@$/d' /run/${RuntimeDirectory}/ddclient.conf
39     '')}
40   '';
44   imports = [
45     (lib.mkChangedOptionModule [ "services" "ddclient" "domain" ] [ "services" "ddclient" "domains" ]
46       (config:
47         let value = lib.getAttrFromPath [ "services" "ddclient" "domain" ] config;
48         in lib.optional (value != "") value))
49     (lib.mkRemovedOptionModule [ "services" "ddclient" "homeDir" ] "")
50     (lib.mkRemovedOptionModule [ "services" "ddclient" "password" ] "Use services.ddclient.passwordFile instead.")
51     (lib.mkRemovedOptionModule [ "services" "ddclient" "ipv6" ] "")
52   ];
54   ###### interface
56   options = {
58     services.ddclient = with lib.types; {
60       enable = lib.mkOption {
61         default = false;
62         type = bool;
63         description = ''
64           Whether to synchronise your machine's IP address with a dynamic DNS provider (e.g. dyndns.org).
65         '';
66       };
68       package = lib.mkOption {
69         type = package;
70         default = pkgs.ddclient;
71         defaultText = lib.literalExpression "pkgs.ddclient";
72         description = ''
73           The ddclient executable package run by the service.
74         '';
75       };
77       domains = lib.mkOption {
78         default = [ "" ];
79         type = listOf str;
80         description = ''
81           Domain name(s) to synchronize.
82         '';
83       };
85       username = lib.mkOption {
86         # For `nsupdate` username contains the path to the nsupdate executable
87         default = lib.optionalString (config.services.ddclient.protocol == "nsupdate") "${pkgs.bind.dnsutils}/bin/nsupdate";
88         defaultText = "";
89         type = str;
90         description = ''
91           User name.
92         '';
93       };
95       passwordFile = lib.mkOption {
96         default = null;
97         type = nullOr str;
98         description = ''
99           A file containing the password or a TSIG key in named format when using the nsupdate protocol.
100         '';
101       };
103       interval = lib.mkOption {
104         default = "10min";
105         type = str;
106         description = ''
107           The interval at which to run the check and update.
108           See {command}`man 7 systemd.time` for the format.
109         '';
110       };
112       configFile = lib.mkOption {
113         default = null;
114         type = nullOr path;
115         description = ''
116           Path to configuration file.
117           When set this overrides the generated configuration from module options.
118         '';
119         example = "/root/nixos/secrets/ddclient.conf";
120       };
122       protocol = lib.mkOption {
123         default = "dyndns2";
124         type = str;
125         description = ''
126           Protocol to use with dynamic DNS provider (see https://ddclient.net/protocols.html ).
127         '';
128       };
130       server = lib.mkOption {
131         default = "";
132         type = str;
133         description = ''
134           Server address.
135         '';
136       };
138       ssl = lib.mkOption {
139         default = true;
140         type = bool;
141         description = ''
142           Whether to use SSL/TLS to connect to dynamic DNS provider.
143         '';
144       };
146       quiet = lib.mkOption {
147         default = false;
148         type = bool;
149         description = ''
150           Print no messages for unnecessary updates.
151         '';
152       };
154       script = lib.mkOption {
155         default = "";
156         type = str;
157         description = ''
158           script as required by some providers.
159         '';
160       };
162       use = lib.mkOption {
163         default = "";
164         type = str;
165         description = ''
166           Method to determine the IP address to send to the dynamic DNS provider.
167         '';
168       };
169       usev4 = lib.mkOption {
170         default = "webv4, webv4=checkip.dyndns.com/, webv4-skip='Current IP Address: '";
171         type = str;
172         description = ''
173           Method to determine the IPv4 address to send to the dynamic DNS provider. Only used if `use` is not set.
174         '';
175       };
176       usev6 = lib.mkOption {
177         default = "webv6, webv6=checkipv6.dyndns.com/, webv6-skip='Current IP Address: '";
178         type = str;
179         description = ''
180           Method to determine the IPv6 address to send to the dynamic DNS provider. Only used if `use` is not set.
181         '';
182       };
184       verbose = lib.mkOption {
185         default = false;
186         type = bool;
187         description = ''
188           Print verbose information.
189         '';
190       };
192       zone = lib.mkOption {
193         default = "";
194         type = str;
195         description = ''
196           zone as required by some providers.
197         '';
198       };
200       extraConfig = lib.mkOption {
201         default = "";
202         type = lines;
203         description = ''
204           Extra configuration. Contents will be added verbatim to the configuration file.
206           ::: {.note}
207           `daemon` should not be added here because it does not work great with the systemd-timer approach the service uses.
208           :::
209         '';
210       };
211     };
212   };
215   ###### implementation
217   config = lib.mkIf config.services.ddclient.enable {
218     warnings = lib.optional (cfg.use != "") "Setting `use` is deprecated, ddclient now supports `usev4` and `usev6` for separate IPv4/IPv6 configuration.";
220     systemd.services.ddclient = {
221       description = "Dynamic DNS Client";
222       wantedBy = [ "multi-user.target" ];
223       after = [ "network.target" ];
224       restartTriggers = lib.optional (cfg.configFile != null) cfg.configFile;
225       path = lib.optional (lib.hasPrefix "if," cfg.use) pkgs.iproute2;
227       serviceConfig = {
228         DynamicUser = true;
229         RuntimeDirectoryMode = "0700";
230         inherit RuntimeDirectory;
231         inherit StateDirectory;
232         Type = "oneshot";
233         ExecStartPre = [ "!${pkgs.writeShellScript "ddclient-prestart" preStart}" ];
234         ExecStart = "${lib.getExe cfg.package} -file /run/${RuntimeDirectory}/ddclient.conf";
235       };
236     };
238     systemd.timers.ddclient = {
239       description = "Run ddclient";
240       wantedBy = [ "timers.target" ];
241       timerConfig = {
242         OnBootSec = cfg.interval;
243         OnUnitInactiveSec = cfg.interval;
244       };
245     };
246   };