at 23.11-pre 3.2 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" { preferLocalBuild = true; } '' 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 = lib.mdDoc "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 = lib.mdDoc "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 = lib.mdDoc "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 = lib.mdDoc '' 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 = literalExpression '' 65 { 66 "@" = ["8.8.8.8" "8.8.4.4"]; 67 "example.com" = ["192.168.100.100"]; 68 } 69 ''; 70 }; 71 72 forwardOnly = mkOption { 73 default = false; 74 type = types.bool; 75 description = lib.mdDoc '' 76 Whether to treat root servers (for @) as caching 77 servers, requesting addresses the same way a client does. This is 78 needed if you want to use e.g. Google DNS as your upstream DNS. 79 ''; 80 }; 81 82 }; 83 }; 84 85 ###### implementation 86 87 config = mkIf config.services.dnscache.enable { 88 environment.systemPackages = [ pkgs.djbdns ]; 89 users.users.dnscache.isSystemUser = true; 90 91 systemd.services.dnscache = { 92 description = "djbdns dnscache server"; 93 wantedBy = [ "multi-user.target" ]; 94 path = with pkgs; [ bash daemontools djbdns ]; 95 preStart = '' 96 rm -rf /var/lib/dnscache 97 dnscache-conf dnscache dnscache /var/lib/dnscache ${config.services.dnscache.ip} 98 rm -rf /var/lib/dnscache/root 99 ln -sf ${dnscache-root} /var/lib/dnscache/root 100 ''; 101 script = '' 102 cd /var/lib/dnscache/ 103 ${optionalString cfg.forwardOnly "export FORWARDONLY=1"} 104 exec ./run 105 ''; 106 }; 107 }; 108}