Remove n0emis as direct maintainer (#365023)
[NixPkgs.git] / nixos / modules / services / networking / dnsmasq.nix
blobdfa6b803516875ce0ab115d9e6fb1a14258bdc17
1 { config, lib, pkgs, ... }:
2 let
3   cfg = config.services.dnsmasq;
4   dnsmasq = cfg.package;
5   stateDir = "/var/lib/dnsmasq";
7   # True values are just put as `name` instead of `name=true`, and false values
8   # are turned to comments (false values are expected to be overrides e.g.
9   # lib.mkForce)
10   formatKeyValue =
11     name: value:
12     if value == true
13     then name
14     else if value == false
15     then "# setting `${name}` explicitly set to false"
16     else lib.generators.mkKeyValueDefault { } "=" name value;
18   settingsFormat = pkgs.formats.keyValue {
19     mkKeyValue = formatKeyValue;
20     listsAsDuplicateKeys = true;
21   };
23   dnsmasqConf = settingsFormat.generate "dnsmasq.conf" cfg.settings;
29   imports = [
30     (lib.mkRenamedOptionModule [ "services" "dnsmasq" "servers" ] [ "services" "dnsmasq" "settings" "server" ])
31     (lib.mkRemovedOptionModule [ "services" "dnsmasq" "extraConfig" ] "This option has been replaced by `services.dnsmasq.settings`")
32   ];
34   ###### interface
36   options = {
38     services.dnsmasq = {
40       enable = lib.mkOption {
41         type = lib.types.bool;
42         default = false;
43         description = ''
44           Whether to run dnsmasq.
45         '';
46       };
48       package = lib.mkPackageOption pkgs "dnsmasq" {};
50       resolveLocalQueries = lib.mkOption {
51         type = lib.types.bool;
52         default = true;
53         description = ''
54           Whether dnsmasq should resolve local queries (i.e. add 127.0.0.1 to
55           /etc/resolv.conf).
56         '';
57       };
59       alwaysKeepRunning = lib.mkOption {
60         type = lib.types.bool;
61         default = false;
62         description = ''
63           If enabled, systemd will always respawn dnsmasq even if shut down manually. The default, disabled, will only restart it on error.
64         '';
65       };
67       settings = lib.mkOption {
68         type = lib.types.submodule {
70           freeformType = settingsFormat.type;
72           options.server = lib.mkOption {
73             type = lib.types.listOf lib.types.str;
74             default = [ ];
75             example = [ "8.8.8.8" "8.8.4.4" ];
76             description = ''
77               The DNS servers which dnsmasq should query.
78             '';
79           };
81         };
82         default = { };
83         description = ''
84           Configuration of dnsmasq. Lists get added one value per line (empty
85           lists and false values don't get added, though false values get
86           turned to comments). Gets merged with
88               {
89                 dhcp-leasefile = "${stateDir}/dnsmasq.leases";
90                 conf-file = optional cfg.resolveLocalQueries "/etc/dnsmasq-conf.conf";
91                 resolv-file = optional cfg.resolveLocalQueries "/etc/dnsmasq-resolv.conf";
92               }
93         '';
94         example = lib.literalExpression ''
95           {
96             domain-needed = true;
97             dhcp-range = [ "192.168.0.2,192.168.0.254" ];
98           }
99         '';
100       };
102     };
104   };
107   ###### implementation
109   config = lib.mkIf cfg.enable {
111     services.dnsmasq.settings = {
112       dhcp-leasefile = lib.mkDefault "${stateDir}/dnsmasq.leases";
113       conf-file = lib.mkDefault (lib.optional cfg.resolveLocalQueries "/etc/dnsmasq-conf.conf");
114       resolv-file = lib.mkDefault (lib.optional cfg.resolveLocalQueries "/etc/dnsmasq-resolv.conf");
115     };
117     networking.nameservers =
118       lib.optional cfg.resolveLocalQueries "127.0.0.1";
120     services.dbus.packages = [ dnsmasq ];
122     users.users.dnsmasq = {
123       isSystemUser = true;
124       group = "dnsmasq";
125       description = "Dnsmasq daemon user";
126     };
127     users.groups.dnsmasq = {};
129     networking.resolvconf = lib.mkIf cfg.resolveLocalQueries {
130       useLocalResolver = lib.mkDefault true;
132       extraConfig = ''
133         dnsmasq_conf=/etc/dnsmasq-conf.conf
134         dnsmasq_resolv=/etc/dnsmasq-resolv.conf
135       '';
137       subscriberFiles = [
138         "/etc/dnsmasq-conf.conf"
139         "/etc/dnsmasq-resolv.conf"
140       ];
141     };
143     systemd.services.dnsmasq = {
144         description = "Dnsmasq Daemon";
145         after = [ "network.target" "systemd-resolved.service" ];
146         wantedBy = [ "multi-user.target" ];
147         path = [ dnsmasq ];
148         preStart = ''
149           mkdir -m 755 -p ${stateDir}
150           touch ${stateDir}/dnsmasq.leases
151           chown -R dnsmasq ${stateDir}
152           touch /etc/dnsmasq-{conf,resolv}.conf
153           dnsmasq --test
154         '';
155         serviceConfig = {
156           Type = "dbus";
157           BusName = "uk.org.thekelleys.dnsmasq";
158           ExecStart = "${dnsmasq}/bin/dnsmasq -k --enable-dbus --user=dnsmasq -C ${dnsmasqConf}";
159           ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
160           PrivateTmp = true;
161           ProtectSystem = true;
162           ProtectHome = true;
163           Restart = if cfg.alwaysKeepRunning then "always" else "on-failure";
164         };
165         restartTriggers = [ config.environment.etc.hosts.source ];
166     };
167   };
169   meta.doc = ./dnsmasq.md;