at 17.09-beta 3.4 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 isLocalAddress = x: substring 0 3 x == "::1" || substring 0 9 x == "127.0.0.1"; 16 17 forward = 18 optionalString (any isLocalAddress cfg.forwardAddresses) '' 19 do-not-query-localhost: no 20 '' + 21 optionalString (cfg.forwardAddresses != []) '' 22 forward-zone: 23 name: . 24 '' + 25 concatMapStringsSep "\n" (x: " forward-addr: ${x}") cfg.forwardAddresses; 26 27 rootTrustAnchorFile = "${stateDir}/root.key"; 28 29 trustAnchor = optionalString cfg.enableRootTrustAnchor 30 "auto-trust-anchor-file: ${rootTrustAnchorFile}"; 31 32 confFile = pkgs.writeText "unbound.conf" '' 33 server: 34 directory: "${stateDir}" 35 username: unbound 36 chroot: "${stateDir}" 37 pidfile: "" 38 ${interfaces} 39 ${access} 40 ${trustAnchor} 41 ${cfg.extraConfig} 42 ${forward} 43 ''; 44 45in 46 47{ 48 49 ###### interface 50 51 options = { 52 services.unbound = { 53 54 enable = mkEnableOption "Unbound domain name server"; 55 56 allowedAccess = mkOption { 57 default = [ "127.0.0.0/24" ]; 58 type = types.listOf types.str; 59 description = "What networks are allowed to use unbound as a resolver."; 60 }; 61 62 interfaces = mkOption { 63 default = [ "127.0.0.1" "::1" ]; 64 type = types.listOf types.str; 65 description = "What addresses the server should listen on."; 66 }; 67 68 forwardAddresses = mkOption { 69 default = [ ]; 70 type = types.listOf types.str; 71 description = "What servers to forward queries to."; 72 }; 73 74 enableRootTrustAnchor = mkOption { 75 default = true; 76 type = types.bool; 77 description = "Use and update root trust anchor for DNSSEC validation."; 78 }; 79 80 extraConfig = mkOption { 81 default = ""; 82 type = types.lines; 83 description = '' 84 Extra unbound config. See 85 <citerefentry><refentrytitle>unbound.conf</refentrytitle><manvolnum>8 86 </manvolnum></citerefentry>. 87 ''; 88 }; 89 90 }; 91 }; 92 93 ###### implementation 94 95 config = mkIf cfg.enable { 96 97 environment.systemPackages = [ pkgs.unbound ]; 98 99 users.users.unbound = { 100 description = "unbound daemon user"; 101 isSystemUser = true; 102 }; 103 104 systemd.services.unbound = { 105 description = "Unbound recursive Domain Name Server"; 106 after = [ "network.target" ]; 107 before = [ "nss-lookup.target" ]; 108 wants = [" nss-lookup.target" ]; 109 wantedBy = [ "multi-user.target" ]; 110 111 preStart = '' 112 mkdir -m 0755 -p ${stateDir}/dev/ 113 cp ${confFile} ${stateDir}/unbound.conf 114 ${optionalString cfg.enableRootTrustAnchor '' 115 ${pkgs.unbound}/bin/unbound-anchor -a ${rootTrustAnchorFile} 116 chown unbound ${stateDir} ${rootTrustAnchorFile} 117 ''} 118 touch ${stateDir}/dev/random 119 ${pkgs.utillinux}/bin/mount --bind -n /dev/urandom ${stateDir}/dev/random 120 ''; 121 122 serviceConfig = { 123 ExecStart = "${pkgs.unbound}/bin/unbound -d -c ${stateDir}/unbound.conf"; 124 ExecStopPost="${pkgs.utillinux}/bin/umount ${stateDir}/dev/random"; 125 126 ProtectSystem = true; 127 ProtectHome = true; 128 PrivateDevices = true; 129 }; 130 }; 131 132 }; 133 134}