{ config, lib, pkgs, ... }: with lib; let cfg = config.services.unbound; username = "unbound"; stateDir = "/var/lib/unbound"; access = concatMapStrings (x: " access-control: ${x} allow\n") cfg.allowedAccess; interfaces = concatMapStrings (x: " interface: ${x}\n") cfg.interfaces; forward = optionalString (length cfg.forwardAddresses != 0) "forward-zone:\n name: .\n" + concatMapStrings (x: " forward-addr: ${x}\n") cfg.forwardAddresses; confFile = pkgs.writeText "unbound.conf" '' server: directory: "${stateDir}" username: ${username} # make sure unbound can access entropy from inside the chroot. # e.g. on linux the use these commands (on BSD, devfs(8) is used): # mount --bind -n /dev/random /etc/unbound/dev/random # and mount --bind -n /dev/log /etc/unbound/dev/log chroot: "${stateDir}" # logfile: "${stateDir}/unbound.log" #uncomment to use logfile. pidfile: "${stateDir}/unbound.pid" verbosity: 1 # uncomment and increase to get more logging. ${interfaces} ${access} ${forward} ${cfg.extraConfig} ''; in { ###### interface options = { services.unbound = { enable = mkOption { default = false; description = "Whether to enable the Unbound domain name server."; }; allowedAccess = mkOption { default = ["127.0.0.0/24"]; description = "What networks are allowed to use unbound as a resolver."; }; interfaces = mkOption { default = [ "127.0.0.1" "::1" ]; description = "What addresses the server should listen on."; }; forwardAddresses = mkOption { default = [ ]; description = "What servers to forward queries to."; }; extraConfig = mkOption { default = ""; description = "Extra lines of unbound config."; }; }; }; ###### implementation config = mkIf cfg.enable { environment.systemPackages = [ pkgs.unbound ]; users.extraUsers = singleton { name = username; uid = config.ids.uids.unbound; description = "unbound daemon user"; home = stateDir; createHome = true; }; systemd.services.unbound = { description="Unbound recursive Domain Name Server"; after = [ "network.target" ]; before = [ "nss-lookup.target" ]; wants = [" nss-lookup.target" ]; wantedBy = [ "multi-user.target" ]; path = [ pkgs.unbound ]; serviceConfig.ExecStart = "${pkgs.unbound}/sbin/unbound -d -c ${confFile}"; }; }; }