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 ${ concatMapStrings
28 ({ name, file, master ? true, slaves ? [], masters ? [] }:
29 ''
30 zone "${name}" {
31 type ${if master then "master" else "slave"};
32 file "${file}";
33 ${ if master then
34 ''
35 allow-transfer {
36 ${concatMapStrings (ip: "${ip};\n") slaves}
37 };
38 ''
39 else
40 ''
41 masters {
42 ${concatMapStrings (ip: "${ip};\n") masters}
43 };
44 ''
45 }
46 allow-query { any; };
47 };
48 '')
49 cfg.zones }
50 '';
51
52in
53
54{
55
56 ###### interface
57
58 options = {
59
60 services.bind = {
61
62 enable = mkOption {
63 default = false;
64 description = "
65 Whether to enable BIND domain name server.
66 ";
67 };
68
69 cacheNetworks = mkOption {
70 default = ["127.0.0.0/24"];
71 description = "
72 What networks are allowed to use us as a resolver.
73 ";
74 };
75
76 blockedNetworks = mkOption {
77 default = [];
78 description = "
79 What networks are just blocked.
80 ";
81 };
82
83 ipv4Only = mkOption {
84 default = false;
85 description = "
86 Only use ipv4, even if the host supports ipv6.
87 ";
88 };
89
90 forwarders = mkOption {
91 default = config.networking.nameservers;
92 description = "
93 List of servers we should forward requests to.
94 ";
95 };
96
97 zones = mkOption {
98 default = [];
99 description = "
100 List of zones we claim authority over.
101 master=false means slave server; slaves means addresses
102 who may request zone transfer.
103 ";
104 example = [{
105 name = "example.com";
106 master = false;
107 file = "/var/dns/example.com";
108 masters = ["192.168.0.1"];
109 slaves = [];
110 }];
111 };
112
113 configFile = mkOption {
114 default = confFile;
115 description = "
116 Overridable config file to use for named. By default, that
117 generated by nixos.
118 ";
119 };
120
121 };
122
123 };
124
125
126 ###### implementation
127
128 config = mkIf config.services.bind.enable {
129
130 users.extraUsers = singleton
131 { name = bindUser;
132 uid = config.ids.uids.bind;
133 description = "BIND daemon user";
134 };
135
136 jobs.bind =
137 { description = "BIND name server job";
138
139 startOn = "started network-interfaces";
140
141 preStart =
142 ''
143 ${pkgs.coreutils}/bin/mkdir -p /var/run/named
144 chown ${bindUser} /var/run/named
145 '';
146
147 exec = "${pkgs.bind}/sbin/named -u ${bindUser} ${optionalString cfg.ipv4Only "-4"} -c ${cfg.configFile} -f";
148 };
149
150 };
151
152}