at 16.09-beta 3.1 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 cfg = config.services.unbound; 8 9 stateDir = "/var/lib/unbound"; 10 11 access = concatMapStrings (x: " access-control: ${x} allow\n") cfg.allowedAccess; 12 13 interfaces = concatMapStrings (x: " interface: ${x}\n") cfg.interfaces; 14 15 forward = optionalString (length cfg.forwardAddresses != 0) 16 "forward-zone:\n name: .\n" + 17 concatMapStrings (x: " forward-addr: ${x}\n") cfg.forwardAddresses; 18 19 rootTrustAnchorFile = "${stateDir}/root.key"; 20 21 trustAnchor = optionalString cfg.enableRootTrustAnchor 22 "auto-trust-anchor-file: ${rootTrustAnchorFile}"; 23 24 confFile = pkgs.writeText "unbound.conf" '' 25 server: 26 directory: "${stateDir}" 27 username: unbound 28 chroot: "${stateDir}" 29 pidfile: "" 30 ${interfaces} 31 ${access} 32 ${trustAnchor} 33 ${cfg.extraConfig} 34 ${forward} 35 ''; 36 37in 38 39{ 40 41 ###### interface 42 43 options = { 44 services.unbound = { 45 46 enable = mkEnableOption "Unbound domain name server"; 47 48 allowedAccess = mkOption { 49 default = [ "127.0.0.0/24" ]; 50 type = types.listOf types.str; 51 description = "What networks are allowed to use unbound as a resolver."; 52 }; 53 54 interfaces = mkOption { 55 default = [ "127.0.0.1" "::1" ]; 56 type = types.listOf types.str; 57 description = "What addresses the server should listen on."; 58 }; 59 60 forwardAddresses = mkOption { 61 default = [ ]; 62 type = types.listOf types.str; 63 description = "What servers to forward queries to."; 64 }; 65 66 enableRootTrustAnchor = mkOption { 67 default = true; 68 type = types.bool; 69 description = "Use and update root trust anchor for DNSSEC validation."; 70 }; 71 72 extraConfig = mkOption { 73 default = ""; 74 type = types.str; 75 description = "Extra lines of unbound config."; 76 }; 77 78 }; 79 }; 80 81 ###### implementation 82 83 config = mkIf cfg.enable { 84 85 environment.systemPackages = [ pkgs.unbound ]; 86 87 users.extraUsers = singleton { 88 name = "unbound"; 89 uid = config.ids.uids.unbound; 90 description = "unbound daemon user"; 91 home = stateDir; 92 createHome = true; 93 }; 94 95 systemd.services.unbound = { 96 description = "Unbound recursive Domain Name Server"; 97 after = [ "network.target" ]; 98 before = [ "nss-lookup.target" ]; 99 wants = [" nss-lookup.target" ]; 100 wantedBy = [ "multi-user.target" ]; 101 102 preStart = '' 103 mkdir -m 0755 -p ${stateDir}/dev/ 104 cp ${confFile} ${stateDir}/unbound.conf 105 ${optionalString cfg.enableRootTrustAnchor '' 106 ${pkgs.unbound}/bin/unbound-anchor -a ${rootTrustAnchorFile} 107 chown unbound ${stateDir} ${rootTrustAnchorFile} 108 ''} 109 touch ${stateDir}/dev/random 110 ${pkgs.utillinux}/bin/mount --bind -n /dev/random ${stateDir}/dev/random 111 ''; 112 113 serviceConfig = { 114 ExecStart = "${pkgs.unbound}/bin/unbound -d -c ${stateDir}/unbound.conf"; 115 ExecStopPost="${pkgs.utillinux}/bin/umount ${stateDir}/dev/random"; 116 }; 117 }; 118 119 }; 120 121}