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}