python312Packages.aiohomeconnect: 0.10.0 -> 0.11.0 (#374011)
[NixPkgs.git] / nixos / modules / services / networking / hickory-dns.nix
blob6a6570e5801725e55582bb5677a649b9df3bcb79
1 { config, lib, pkgs, ... }:
2 let
3   cfg = config.services.hickory-dns;
4   toml = pkgs.formats.toml { };
6   zoneType = lib.types.submodule ({ config, ... }: {
7     freeformType = toml.type;
8     options = with lib; {
9       zone = mkOption {
10         type = types.str;
11         description = ''
12           Zone name, like "example.com", "localhost", or "0.0.127.in-addr.arpa".
13         '';
14       };
15       zone_type = mkOption {
16         type = types.enum [ "Primary" "Secondary" "Hint" "Forward" ];
17         default = "Primary";
18         description = ''
19           One of:
20           - "Primary" (the master, authority for the zone).
21           - "Secondary" (the slave, replicated from the primary).
22           - "Hint" (a cached zone with recursive resolver abilities).
23           - "Forward" (a cached zone where all requests are forwarded to another resolver).
25           For more details about these zone types, consult the documentation for BIND,
26           though note that hickory-dns supports only a subset of BIND's zone types:
27           <https://bind9.readthedocs.io/en/v9_18_4/reference.html#type>
28         '';
29       };
30       file = mkOption {
31         type = types.either types.path types.str;
32         default = "${config.zone}.zone";
33         defaultText = literalExpression ''"''${config.zone}.zone"'';
34         description = ''
35           Path to the .zone file.
36           If not fully-qualified, this path will be interpreted relative to the `directory` option.
37           If omitted, defaults to the value of the `zone` option suffixed with ".zone".
38         '';
39       };
40     };
41   });
44   meta.maintainers = with lib.maintainers; [ colinsane ];
46   imports = with lib; [
47     (mkRenamedOptionModule [ "services" "trust-dns" "enable" ] [ "services" "hickory-dns" "enable" ])
48     (mkRenamedOptionModule [ "services" "trust-dns" "package" ] [ "services" "hickory-dns" "package" ])
49     (mkRenamedOptionModule [ "services" "trust-dns" "settings" ] [ "services" "hickory-dns" "settings" ])
50     (mkRenamedOptionModule [ "services" "trust-dns" "quiet" ] [ "services" "hickory-dns" "quiet" ])
51     (mkRenamedOptionModule [ "services" "trust-dns" "debug" ] [ "services" "hickory-dns" "debug" ])
52   ];
54   options = {
55     services.hickory-dns = with lib; {
56       enable = mkEnableOption "hickory-dns";
57       package = mkPackageOption pkgs "hickory-dns" {
58         extraDescription = ''
59           ::: {.note}
60           The package must provide `meta.mainProgram` which names the server binary; any other utilities (client, resolver) are not needed.
61           :::
62         '';
63       };
64       quiet = mkOption {
65         type = types.bool;
66         default = false;
67         description = ''
68           Log ERROR level messages only.
69           This option is mutually exclusive with the `debug` option.
70           If neither `quiet` nor `debug` are enabled, logging defaults to the INFO level.
71         '';
72       };
73       debug = mkOption {
74         type = types.bool;
75         default = false;
76         description = ''
77           Log DEBUG, INFO, WARN and ERROR messages.
78           This option is mutually exclusive with the `debug` option.
79           If neither `quiet` nor `debug` are enabled, logging defaults to the INFO level.
80         '';
81       };
82       configFile = mkOption {
83         type = types.path;
84         default = toml.generate "hickory-dns.toml" (
85           lib.filterAttrsRecursive (_: v: v != null) cfg.settings
86         );
87         defaultText = lib.literalExpression ''
88           let toml = pkgs.formats.toml { }; in toml.generate "hickory-dns.toml" cfg.settings
89         '';
90         description = ''
91           Path to an existing toml file to configure hickory-dns with.
93           This can usually be left unspecified, in which case it will be
94           generated from the values in `settings`.
95           If manually specified, then the options in `settings` are ignored.
96         '';
97       };
98       settings = mkOption {
99         description = ''
100           Settings for hickory-dns. The options enumerated here are not exhaustive.
101           Refer to upstream documentation for all available options:
102           - [Example settings](https://github.com/hickory-dns/hickory-dns/blob/main/tests/test-data/test_configs/example.toml)
103         '';
104         type = types.submodule {
105           freeformType = toml.type;
106           options = {
107             listen_addrs_ipv4 = mkOption {
108               type = types.listOf types.str;
109               default = [ "0.0.0.0" ];
110               description = ''
111                 List of ipv4 addresses on which to listen for DNS queries.
112               '';
113             };
114             listen_addrs_ipv6 = mkOption {
115               type = types.listOf types.str;
116               default = lib.optional config.networking.enableIPv6 "::0";
117               defaultText = literalExpression ''lib.optional config.networking.enableIPv6 "::0"'';
118               description = ''
119                 List of ipv6 addresses on which to listen for DNS queries.
120               '';
121             };
122             listen_port = mkOption {
123               type = types.port;
124               default = 53;
125               description = ''
126                 Port to listen on (applies to all listen addresses).
127               '';
128             };
129             directory = mkOption {
130               type = types.str;
131               default = "/var/lib/hickory-dns";
132               description = ''
133                 The directory in which hickory-dns should look for .zone files,
134                 whenever zones aren't specified by absolute path.
135               '';
136             };
137             zones = mkOption {
138               description = "List of zones to serve.";
139               default = [];
140               type = types.listOf (types.coercedTo types.str (zone: { inherit zone; }) zoneType);
141             };
142           };
143         };
144       };
145     };
146   };
148   config = lib.mkIf cfg.enable {
149     systemd.services.hickory-dns = {
150       description = "hickory-dns Domain Name Server";
151       unitConfig.Documentation = "https://hickory-dns.org/";
152       serviceConfig = {
153         ExecStart =
154         let
155           flags =  (lib.optional cfg.debug "--debug") ++ (lib.optional cfg.quiet "--quiet");
156           flagsStr = builtins.concatStringsSep " " flags;
157         in ''
158           ${lib.getExe cfg.package} --config ${cfg.configFile} ${flagsStr}
159         '';
160         Type = "simple";
161         Restart = "on-failure";
162         RestartSec = "10s";
163         DynamicUser = true;
165         StateDirectory = "hickory-dns";
166         ReadWritePaths = [ cfg.settings.directory ];
168         AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
169         CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
170         LockPersonality = true;
171         MemoryDenyWriteExecute = true;
172         NoNewPrivileges = true;
173         PrivateDevices = true;
174         PrivateMounts = true;
175         PrivateTmp = true;
176         ProtectClock = true;
177         ProtectControlGroups = true;
178         ProtectHome = true;
179         ProtectHostname = true;
180         ProtectKernelLogs = true;
181         ProtectKernelModules = true;
182         ProtectKernelTunables = true;
183         ProtectProc = "invisible";
184         ProtectSystem = "full";
185         RemoveIPC = true;
186         RestrictAddressFamilies = [ "AF_INET AF_INET6" ];
187         RestrictNamespaces = true;
188         RestrictSUIDSGID = true;
189         SystemCallArchitectures = "native";
190         SystemCallFilter = [ "@system-service" "~@privileged" "~@resources" ];
191       };
192       after = [ "network.target" ];
193       wantedBy = [ "multi-user.target" ];
194     };
195   };