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 confFile = pkgs.writeText "unbound.conf" ''
20 server:
21 directory: "${stateDir}"
22 username: unbound
23 chroot: "${stateDir}"
24 pidfile: ""
25 ${interfaces}
26 ${access}
27 ${cfg.extraConfig}
28 ${forward}
29 '';
30
31in
32
33{
34
35 ###### interface
36
37 options = {
38 services.unbound = {
39
40 enable = mkOption {
41 default = false;
42 description = "Whether to enable the Unbound domain name server.";
43 };
44
45 allowedAccess = mkOption {
46 default = ["127.0.0.0/24"];
47 description = "What networks are allowed to use unbound as a resolver.";
48 };
49
50 interfaces = mkOption {
51 default = [ "127.0.0.1" "::1" ];
52 description = "What addresses the server should listen on.";
53 };
54
55 forwardAddresses = mkOption {
56 default = [ ];
57 description = "What servers to forward queries to.";
58 };
59
60 extraConfig = mkOption {
61 default = "";
62 description = "Extra lines of unbound config.";
63 };
64
65 };
66 };
67
68 ###### implementation
69
70 config = mkIf cfg.enable {
71
72 environment.systemPackages = [ pkgs.unbound ];
73
74 users.extraUsers = singleton {
75 name = "unbound";
76 uid = config.ids.uids.unbound;
77 description = "unbound daemon user";
78 home = stateDir;
79 createHome = true;
80 };
81
82 systemd.services.unbound = {
83 description="Unbound recursive Domain Name Server";
84 after = [ "network.target" ];
85 before = [ "nss-lookup.target" ];
86 wants = [" nss-lookup.target" ];
87 wantedBy = [ "multi-user.target" ];
88
89 preStart = ''
90 mkdir -m 0755 -p ${stateDir}/dev/
91 cp ${confFile} ${stateDir}/unbound.conf
92 chown unbound ${stateDir}
93 touch ${stateDir}/dev/random
94 ${pkgs.utillinux}/bin/mount --bind -n /dev/random ${stateDir}/dev/random
95 '';
96
97 serviceConfig = {
98 ExecStart = "${pkgs.unbound}/sbin/unbound -d -c ${stateDir}/unbound.conf";
99 ExecStopPost="${pkgs.utillinux}/bin/umount ${stateDir}/dev/random";
100 };
101 };
102
103 };
104
105}