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