1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.services.bind;
8
9 bindUser = "named";
10
11 confFile = pkgs.writeText "named.conf"
12 ''
13 acl cachenetworks { ${concatMapStrings (entry: " ${entry}; ") cfg.cacheNetworks} };
14 acl badnetworks { ${concatMapStrings (entry: " ${entry}; ") cfg.blockedNetworks} };
15
16 options {
17 listen-on {any;};
18 listen-on-v6 {any;};
19 allow-query { cachenetworks; };
20 blackhole { badnetworks; };
21 forward first;
22 forwarders { ${concatMapStrings (entry: " ${entry}; ") cfg.forwarders} };
23 directory "/var/run/named";
24 pid-file "/var/run/named/named.pid";
25 };
26
27 ${cfg.extraConfig}
28
29 ${ concatMapStrings
30 ({ name, file, master ? true, slaves ? [], masters ? [] }:
31 ''
32 zone "${name}" {
33 type ${if master then "master" else "slave"};
34 file "${file}";
35 ${ if master then
36 ''
37 allow-transfer {
38 ${concatMapStrings (ip: "${ip};\n") slaves}
39 };
40 ''
41 else
42 ''
43 masters {
44 ${concatMapStrings (ip: "${ip};\n") masters}
45 };
46 ''
47 }
48 allow-query { any; };
49 };
50 '')
51 cfg.zones }
52 '';
53
54in
55
56{
57
58 ###### interface
59
60 options = {
61
62 services.bind = {
63
64 enable = mkOption {
65 default = false;
66 description = "
67 Whether to enable BIND domain name server.
68 ";
69 };
70
71 cacheNetworks = mkOption {
72 default = ["127.0.0.0/24"];
73 description = "
74 What networks are allowed to use us as a resolver.
75 ";
76 };
77
78 blockedNetworks = mkOption {
79 default = [];
80 description = "
81 What networks are just blocked.
82 ";
83 };
84
85 ipv4Only = mkOption {
86 default = false;
87 description = "
88 Only use ipv4, even if the host supports ipv6.
89 ";
90 };
91
92 forwarders = mkOption {
93 default = config.networking.nameservers;
94 description = "
95 List of servers we should forward requests to.
96 ";
97 };
98
99 zones = mkOption {
100 default = [];
101 description = "
102 List of zones we claim authority over.
103 master=false means slave server; slaves means addresses
104 who may request zone transfer.
105 ";
106 example = [{
107 name = "example.com";
108 master = false;
109 file = "/var/dns/example.com";
110 masters = ["192.168.0.1"];
111 slaves = [];
112 }];
113 };
114
115 extraConfig = mkOption {
116 default = "";
117 description = "
118 Extra lines to be added verbatim to the generated named configuration file.
119 ";
120 };
121
122 configFile = mkOption {
123 type = types.path;
124 default = confFile;
125 defaultText = "confFile";
126 description = "
127 Overridable config file to use for named. By default, that
128 generated by nixos.
129 ";
130 };
131
132 };
133
134 };
135
136
137 ###### implementation
138
139 config = mkIf config.services.bind.enable {
140
141 users.extraUsers = singleton
142 { name = bindUser;
143 uid = config.ids.uids.bind;
144 description = "BIND daemon user";
145 };
146
147 systemd.services.bind = {
148 description = "BIND name server job";
149 after = [ "network-interfaces.target" ];
150 wantedBy = [ "multi-user.target" ];
151
152 preStart = ''
153 ${pkgs.coreutils}/bin/mkdir -p /var/run/named
154 chown ${bindUser} /var/run/named
155 '';
156
157 script = "${pkgs.bind}/sbin/named -u ${bindUser} ${optionalString cfg.ipv4Only "-4"} -c ${cfg.configFile} -f";
158 };
159 };
160}