at 18.09-beta 3.1 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.dnscache; 7 8 dnscache-root = pkgs.runCommand "dnscache-root" {} '' 9 mkdir -p $out/{servers,ip} 10 11 ${concatMapStrings (ip: '' 12 touch "$out/ip/"${lib.escapeShellArg ip} 13 '') cfg.clientIps} 14 15 ${concatStrings (mapAttrsToList (host: ips: '' 16 ${concatMapStrings (ip: '' 17 echo ${lib.escapeShellArg ip} >> "$out/servers/"${lib.escapeShellArg host} 18 '') ips} 19 '') cfg.domainServers)} 20 21 # if a list of root servers was not provided in config, copy it 22 # over. (this is also done by dnscache-conf, but we 'rm -rf 23 # /var/lib/dnscache/root' below & replace it wholesale with this, 24 # so we have to ensure servers/@ exists ourselves.) 25 if [ ! -e $out/servers/@ ]; then 26 # symlink does not work here, due chroot 27 cp ${pkgs.djbdns}/etc/dnsroots.global $out/servers/@; 28 fi 29 ''; 30 31in { 32 33 ###### interface 34 35 options = { 36 services.dnscache = { 37 38 enable = mkOption { 39 default = false; 40 type = types.bool; 41 description = "Whether to run the dnscache caching dns server."; 42 }; 43 44 ip = mkOption { 45 default = "0.0.0.0"; 46 type = types.str; 47 description = "IP address on which to listen for connections."; 48 }; 49 50 clientIps = mkOption { 51 default = [ "127.0.0.1" ]; 52 type = types.listOf types.str; 53 description = "Client IP addresses (or prefixes) from which to accept connections."; 54 example = ["192.168" "172.23.75.82"]; 55 }; 56 57 domainServers = mkOption { 58 default = { }; 59 type = types.attrsOf (types.listOf types.str); 60 description = '' 61 Table of {hostname: server} pairs to use as authoritative servers for hosts (and subhosts). 62 If entry for @ is not specified predefined list of root servers is used. 63 ''; 64 example = { 65 "@" = ["8.8.8.8" "8.8.4.4"]; 66 "example.com" = ["192.168.100.100"]; 67 }; 68 }; 69 70 forwardOnly = mkOption { 71 default = false; 72 type = types.bool; 73 description = '' 74 Whether to treat root servers (for @) as caching 75 servers, requesting addresses the same way a client does. This is 76 needed if you want to use e.g. Google DNS as your upstream DNS. 77 ''; 78 }; 79 80 }; 81 }; 82 83 ###### implementation 84 85 config = mkIf config.services.dnscache.enable { 86 environment.systemPackages = [ pkgs.djbdns ]; 87 users.users.dnscache = {}; 88 89 systemd.services.dnscache = { 90 description = "djbdns dnscache server"; 91 wantedBy = [ "multi-user.target" ]; 92 path = with pkgs; [ bash daemontools djbdns ]; 93 preStart = '' 94 rm -rf /var/lib/dnscache 95 dnscache-conf dnscache dnscache /var/lib/dnscache ${config.services.dnscache.ip} 96 rm -rf /var/lib/dnscache/root 97 ln -sf ${dnscache-root} /var/lib/dnscache/root 98 ''; 99 script = '' 100 cd /var/lib/dnscache/ 101 ${optionalString cfg.forwardOnly "export FORWARDONLY=1"} 102 exec ./run 103 ''; 104 }; 105 }; 106}