nixpkgs/nixos/modules/services/networking/unbound.nix

185 lines
5.0 KiB
Nix
Raw Normal View History

{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.unbound;
stateDir = "/var/lib/unbound";
access = concatMapStringsSep "\n " (x: "access-control: ${x} allow") cfg.allowedAccess;
interfaces = concatMapStringsSep "\n " (x: "interface: ${x}") cfg.interfaces;
isLocalAddress = x: substring 0 3 x == "::1" || substring 0 9 x == "127.0.0.1";
forward =
optionalString (any isLocalAddress cfg.forwardAddresses) ''
do-not-query-localhost: no
nixos/modules/services/networking/unbound: update systemd unit Previously we just applied a very minimal set of restrictions and trusted unbound to properly drop root privs and capabilities. With this change I am (for the most part) just using the upstream example unit file for unbound. The main difference is that we start unbound was `unbound` user with the required capabilities instead of letting unbound do the chroot & uid/gid changes. The upstream unit configuration this is based on is a lot stricter with all kinds of permissions then our previous variant. It also came with the default of having the `Type` set to `notify`, therefore we are also using the `unbound-with-systemd` package here. Unbound will start up, read the configuration files and start listening on the configured ports before systemd will declare the unit "running". This will likely help with startup order and the occasional race condition during system activation where the DNS service is started but not yet ready to answer queries. Aditionally to the much stricter runtime environmet I removed the `/dev/urandom` mount lines we previously had in the code (that would randomly fail during `stop`-phase). The `preStart` script is now only required if we enabled the trust anchor updates (which are still enabled by default). Another beneefit of the refactoring is that we can now issue reloads via either `pkill -HUP unbound` or `systemctl reload unbound` to reload the running configuration without taking the daemon offline. A prerequisite of this was that unbound configuration is available on a well known path on the file system. I went for /etc/unbound/unbound.conf as that is the default in the CLI tooling which in turn enables us to use `unbound-control` without passing a custom configuration location.
2020-05-07 11:17:14 +00:00
''
+ optionalString (cfg.forwardAddresses != []) ''
forward-zone:
name: .
nixos/modules/services/networking/unbound: update systemd unit Previously we just applied a very minimal set of restrictions and trusted unbound to properly drop root privs and capabilities. With this change I am (for the most part) just using the upstream example unit file for unbound. The main difference is that we start unbound was `unbound` user with the required capabilities instead of letting unbound do the chroot & uid/gid changes. The upstream unit configuration this is based on is a lot stricter with all kinds of permissions then our previous variant. It also came with the default of having the `Type` set to `notify`, therefore we are also using the `unbound-with-systemd` package here. Unbound will start up, read the configuration files and start listening on the configured ports before systemd will declare the unit "running". This will likely help with startup order and the occasional race condition during system activation where the DNS service is started but not yet ready to answer queries. Aditionally to the much stricter runtime environmet I removed the `/dev/urandom` mount lines we previously had in the code (that would randomly fail during `stop`-phase). The `preStart` script is now only required if we enabled the trust anchor updates (which are still enabled by default). Another beneefit of the refactoring is that we can now issue reloads via either `pkill -HUP unbound` or `systemctl reload unbound` to reload the running configuration without taking the daemon offline. A prerequisite of this was that unbound configuration is available on a well known path on the file system. I went for /etc/unbound/unbound.conf as that is the default in the CLI tooling which in turn enables us to use `unbound-control` without passing a custom configuration location.
2020-05-07 11:17:14 +00:00
''
+ concatMapStringsSep "\n" (x: " forward-addr: ${x}") cfg.forwardAddresses;
rootTrustAnchorFile = "${stateDir}/root.key";
trustAnchor = optionalString cfg.enableRootTrustAnchor
"auto-trust-anchor-file: ${rootTrustAnchorFile}";
confFile = pkgs.writeText "unbound.conf" ''
server:
nixos/modules/services/networking/unbound: update systemd unit Previously we just applied a very minimal set of restrictions and trusted unbound to properly drop root privs and capabilities. With this change I am (for the most part) just using the upstream example unit file for unbound. The main difference is that we start unbound was `unbound` user with the required capabilities instead of letting unbound do the chroot & uid/gid changes. The upstream unit configuration this is based on is a lot stricter with all kinds of permissions then our previous variant. It also came with the default of having the `Type` set to `notify`, therefore we are also using the `unbound-with-systemd` package here. Unbound will start up, read the configuration files and start listening on the configured ports before systemd will declare the unit "running". This will likely help with startup order and the occasional race condition during system activation where the DNS service is started but not yet ready to answer queries. Aditionally to the much stricter runtime environmet I removed the `/dev/urandom` mount lines we previously had in the code (that would randomly fail during `stop`-phase). The `preStart` script is now only required if we enabled the trust anchor updates (which are still enabled by default). Another beneefit of the refactoring is that we can now issue reloads via either `pkill -HUP unbound` or `systemctl reload unbound` to reload the running configuration without taking the daemon offline. A prerequisite of this was that unbound configuration is available on a well known path on the file system. I went for /etc/unbound/unbound.conf as that is the default in the CLI tooling which in turn enables us to use `unbound-control` without passing a custom configuration location.
2020-05-07 11:17:14 +00:00
ip-freebind: yes
directory: "${stateDir}"
2014-08-27 01:24:09 +00:00
username: unbound
nixos/modules/services/networking/unbound: update systemd unit Previously we just applied a very minimal set of restrictions and trusted unbound to properly drop root privs and capabilities. With this change I am (for the most part) just using the upstream example unit file for unbound. The main difference is that we start unbound was `unbound` user with the required capabilities instead of letting unbound do the chroot & uid/gid changes. The upstream unit configuration this is based on is a lot stricter with all kinds of permissions then our previous variant. It also came with the default of having the `Type` set to `notify`, therefore we are also using the `unbound-with-systemd` package here. Unbound will start up, read the configuration files and start listening on the configured ports before systemd will declare the unit "running". This will likely help with startup order and the occasional race condition during system activation where the DNS service is started but not yet ready to answer queries. Aditionally to the much stricter runtime environmet I removed the `/dev/urandom` mount lines we previously had in the code (that would randomly fail during `stop`-phase). The `preStart` script is now only required if we enabled the trust anchor updates (which are still enabled by default). Another beneefit of the refactoring is that we can now issue reloads via either `pkill -HUP unbound` or `systemctl reload unbound` to reload the running configuration without taking the daemon offline. A prerequisite of this was that unbound configuration is available on a well known path on the file system. I went for /etc/unbound/unbound.conf as that is the default in the CLI tooling which in turn enables us to use `unbound-control` without passing a custom configuration location.
2020-05-07 11:17:14 +00:00
chroot: ""
2014-08-27 01:24:09 +00:00
pidfile: ""
nixos/modules/services/networking/unbound: update systemd unit Previously we just applied a very minimal set of restrictions and trusted unbound to properly drop root privs and capabilities. With this change I am (for the most part) just using the upstream example unit file for unbound. The main difference is that we start unbound was `unbound` user with the required capabilities instead of letting unbound do the chroot & uid/gid changes. The upstream unit configuration this is based on is a lot stricter with all kinds of permissions then our previous variant. It also came with the default of having the `Type` set to `notify`, therefore we are also using the `unbound-with-systemd` package here. Unbound will start up, read the configuration files and start listening on the configured ports before systemd will declare the unit "running". This will likely help with startup order and the occasional race condition during system activation where the DNS service is started but not yet ready to answer queries. Aditionally to the much stricter runtime environmet I removed the `/dev/urandom` mount lines we previously had in the code (that would randomly fail during `stop`-phase). The `preStart` script is now only required if we enabled the trust anchor updates (which are still enabled by default). Another beneefit of the refactoring is that we can now issue reloads via either `pkill -HUP unbound` or `systemctl reload unbound` to reload the running configuration without taking the daemon offline. A prerequisite of this was that unbound configuration is available on a well known path on the file system. I went for /etc/unbound/unbound.conf as that is the default in the CLI tooling which in turn enables us to use `unbound-control` without passing a custom configuration location.
2020-05-07 11:17:14 +00:00
# when running under systemd there is no need to daemonize
do-daemonize: no
${interfaces}
${access}
${trustAnchor}
${cfg.extraConfig}
2014-08-27 01:24:09 +00:00
${forward}
'';
in
{
###### interface
options = {
services.unbound = {
2016-08-30 17:28:30 +00:00
enable = mkEnableOption "Unbound domain name server";
2019-12-12 23:49:47 +00:00
package = mkOption {
type = types.package;
nixos/modules/services/networking/unbound: update systemd unit Previously we just applied a very minimal set of restrictions and trusted unbound to properly drop root privs and capabilities. With this change I am (for the most part) just using the upstream example unit file for unbound. The main difference is that we start unbound was `unbound` user with the required capabilities instead of letting unbound do the chroot & uid/gid changes. The upstream unit configuration this is based on is a lot stricter with all kinds of permissions then our previous variant. It also came with the default of having the `Type` set to `notify`, therefore we are also using the `unbound-with-systemd` package here. Unbound will start up, read the configuration files and start listening on the configured ports before systemd will declare the unit "running". This will likely help with startup order and the occasional race condition during system activation where the DNS service is started but not yet ready to answer queries. Aditionally to the much stricter runtime environmet I removed the `/dev/urandom` mount lines we previously had in the code (that would randomly fail during `stop`-phase). The `preStart` script is now only required if we enabled the trust anchor updates (which are still enabled by default). Another beneefit of the refactoring is that we can now issue reloads via either `pkill -HUP unbound` or `systemctl reload unbound` to reload the running configuration without taking the daemon offline. A prerequisite of this was that unbound configuration is available on a well known path on the file system. I went for /etc/unbound/unbound.conf as that is the default in the CLI tooling which in turn enables us to use `unbound-control` without passing a custom configuration location.
2020-05-07 11:17:14 +00:00
default = pkgs.unbound-with-systemd;
defaultText = "pkgs.unbound-with-systemd";
2019-12-12 23:49:47 +00:00
description = "The unbound package to use";
};
allowedAccess = mkOption {
2016-08-30 17:30:28 +00:00
default = [ "127.0.0.0/24" ];
2016-02-15 02:37:45 +00:00
type = types.listOf types.str;
2016-02-07 17:40:15 +00:00
description = "What networks are allowed to use unbound as a resolver.";
};
interfaces = mkOption {
2018-06-12 12:29:25 +00:00
default = [ "127.0.0.1" ] ++ optional config.networking.enableIPv6 "::1";
2016-02-15 02:37:45 +00:00
type = types.listOf types.str;
nixos/modules/services/networking/unbound: update systemd unit Previously we just applied a very minimal set of restrictions and trusted unbound to properly drop root privs and capabilities. With this change I am (for the most part) just using the upstream example unit file for unbound. The main difference is that we start unbound was `unbound` user with the required capabilities instead of letting unbound do the chroot & uid/gid changes. The upstream unit configuration this is based on is a lot stricter with all kinds of permissions then our previous variant. It also came with the default of having the `Type` set to `notify`, therefore we are also using the `unbound-with-systemd` package here. Unbound will start up, read the configuration files and start listening on the configured ports before systemd will declare the unit "running". This will likely help with startup order and the occasional race condition during system activation where the DNS service is started but not yet ready to answer queries. Aditionally to the much stricter runtime environmet I removed the `/dev/urandom` mount lines we previously had in the code (that would randomly fail during `stop`-phase). The `preStart` script is now only required if we enabled the trust anchor updates (which are still enabled by default). Another beneefit of the refactoring is that we can now issue reloads via either `pkill -HUP unbound` or `systemctl reload unbound` to reload the running configuration without taking the daemon offline. A prerequisite of this was that unbound configuration is available on a well known path on the file system. I went for /etc/unbound/unbound.conf as that is the default in the CLI tooling which in turn enables us to use `unbound-control` without passing a custom configuration location.
2020-05-07 11:17:14 +00:00
description = ''
What addresses the server should listen on. This supports the interface syntax documented in
<citerefentry><refentrytitle>unbound.conf</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
'';
};
forwardAddresses = mkOption {
nixos/modules/services/networking/unbound: update systemd unit Previously we just applied a very minimal set of restrictions and trusted unbound to properly drop root privs and capabilities. With this change I am (for the most part) just using the upstream example unit file for unbound. The main difference is that we start unbound was `unbound` user with the required capabilities instead of letting unbound do the chroot & uid/gid changes. The upstream unit configuration this is based on is a lot stricter with all kinds of permissions then our previous variant. It also came with the default of having the `Type` set to `notify`, therefore we are also using the `unbound-with-systemd` package here. Unbound will start up, read the configuration files and start listening on the configured ports before systemd will declare the unit "running". This will likely help with startup order and the occasional race condition during system activation where the DNS service is started but not yet ready to answer queries. Aditionally to the much stricter runtime environmet I removed the `/dev/urandom` mount lines we previously had in the code (that would randomly fail during `stop`-phase). The `preStart` script is now only required if we enabled the trust anchor updates (which are still enabled by default). Another beneefit of the refactoring is that we can now issue reloads via either `pkill -HUP unbound` or `systemctl reload unbound` to reload the running configuration without taking the daemon offline. A prerequisite of this was that unbound configuration is available on a well known path on the file system. I went for /etc/unbound/unbound.conf as that is the default in the CLI tooling which in turn enables us to use `unbound-control` without passing a custom configuration location.
2020-05-07 11:17:14 +00:00
default = [];
2016-02-15 02:37:45 +00:00
type = types.listOf types.str;
2016-02-07 17:40:15 +00:00
description = "What servers to forward queries to.";
};
enableRootTrustAnchor = mkOption {
default = true;
type = types.bool;
description = "Use and update root trust anchor for DNSSEC validation.";
};
extraConfig = mkOption {
2016-02-07 17:40:15 +00:00
default = "";
2016-10-23 17:33:41 +00:00
type = types.lines;
description = ''
Extra unbound config. See
<citerefentry><refentrytitle>unbound.conf</refentrytitle><manvolnum>8
</manvolnum></citerefentry>.
'';
};
};
};
###### implementation
config = mkIf cfg.enable {
2019-12-12 23:49:47 +00:00
environment.systemPackages = [ cfg.package ];
users.users.unbound = {
description = "unbound daemon user";
isSystemUser = true;
};
networking.resolvconf.useLocalResolver = mkDefault true;
nixos/modules/services/networking/unbound: update systemd unit Previously we just applied a very minimal set of restrictions and trusted unbound to properly drop root privs and capabilities. With this change I am (for the most part) just using the upstream example unit file for unbound. The main difference is that we start unbound was `unbound` user with the required capabilities instead of letting unbound do the chroot & uid/gid changes. The upstream unit configuration this is based on is a lot stricter with all kinds of permissions then our previous variant. It also came with the default of having the `Type` set to `notify`, therefore we are also using the `unbound-with-systemd` package here. Unbound will start up, read the configuration files and start listening on the configured ports before systemd will declare the unit "running". This will likely help with startup order and the occasional race condition during system activation where the DNS service is started but not yet ready to answer queries. Aditionally to the much stricter runtime environmet I removed the `/dev/urandom` mount lines we previously had in the code (that would randomly fail during `stop`-phase). The `preStart` script is now only required if we enabled the trust anchor updates (which are still enabled by default). Another beneefit of the refactoring is that we can now issue reloads via either `pkill -HUP unbound` or `systemctl reload unbound` to reload the running configuration without taking the daemon offline. A prerequisite of this was that unbound configuration is available on a well known path on the file system. I went for /etc/unbound/unbound.conf as that is the default in the CLI tooling which in turn enables us to use `unbound-control` without passing a custom configuration location.
2020-05-07 11:17:14 +00:00
environment.etc."unbound/unbound.conf".source = confFile;
systemd.services.unbound = {
2016-08-30 17:30:28 +00:00
description = "Unbound recursive Domain Name Server";
after = [ "network.target" ];
before = [ "nss-lookup.target" ];
2017-10-10 20:08:36 +00:00
wants = [ "nss-lookup.target" ];
wantedBy = [ "multi-user.target" ];
nixos/modules/services/networking/unbound: update systemd unit Previously we just applied a very minimal set of restrictions and trusted unbound to properly drop root privs and capabilities. With this change I am (for the most part) just using the upstream example unit file for unbound. The main difference is that we start unbound was `unbound` user with the required capabilities instead of letting unbound do the chroot & uid/gid changes. The upstream unit configuration this is based on is a lot stricter with all kinds of permissions then our previous variant. It also came with the default of having the `Type` set to `notify`, therefore we are also using the `unbound-with-systemd` package here. Unbound will start up, read the configuration files and start listening on the configured ports before systemd will declare the unit "running". This will likely help with startup order and the occasional race condition during system activation where the DNS service is started but not yet ready to answer queries. Aditionally to the much stricter runtime environmet I removed the `/dev/urandom` mount lines we previously had in the code (that would randomly fail during `stop`-phase). The `preStart` script is now only required if we enabled the trust anchor updates (which are still enabled by default). Another beneefit of the refactoring is that we can now issue reloads via either `pkill -HUP unbound` or `systemctl reload unbound` to reload the running configuration without taking the daemon offline. A prerequisite of this was that unbound configuration is available on a well known path on the file system. I went for /etc/unbound/unbound.conf as that is the default in the CLI tooling which in turn enables us to use `unbound-control` without passing a custom configuration location.
2020-05-07 11:17:14 +00:00
preStart = lib.mkIf cfg.enableRootTrustAnchor ''
${cfg.package}/bin/unbound-anchor -a ${rootTrustAnchorFile} || echo "Root anchor updated!"
2014-08-27 01:24:09 +00:00
'';
nixos/modules/services/networking/unbound: update systemd unit Previously we just applied a very minimal set of restrictions and trusted unbound to properly drop root privs and capabilities. With this change I am (for the most part) just using the upstream example unit file for unbound. The main difference is that we start unbound was `unbound` user with the required capabilities instead of letting unbound do the chroot & uid/gid changes. The upstream unit configuration this is based on is a lot stricter with all kinds of permissions then our previous variant. It also came with the default of having the `Type` set to `notify`, therefore we are also using the `unbound-with-systemd` package here. Unbound will start up, read the configuration files and start listening on the configured ports before systemd will declare the unit "running". This will likely help with startup order and the occasional race condition during system activation where the DNS service is started but not yet ready to answer queries. Aditionally to the much stricter runtime environmet I removed the `/dev/urandom` mount lines we previously had in the code (that would randomly fail during `stop`-phase). The `preStart` script is now only required if we enabled the trust anchor updates (which are still enabled by default). Another beneefit of the refactoring is that we can now issue reloads via either `pkill -HUP unbound` or `systemctl reload unbound` to reload the running configuration without taking the daemon offline. A prerequisite of this was that unbound configuration is available on a well known path on the file system. I went for /etc/unbound/unbound.conf as that is the default in the CLI tooling which in turn enables us to use `unbound-control` without passing a custom configuration location.
2020-05-07 11:17:14 +00:00
restartTriggers = [
confFile
];
2014-08-27 01:24:09 +00:00
serviceConfig = {
nixos/modules/services/networking/unbound: update systemd unit Previously we just applied a very minimal set of restrictions and trusted unbound to properly drop root privs and capabilities. With this change I am (for the most part) just using the upstream example unit file for unbound. The main difference is that we start unbound was `unbound` user with the required capabilities instead of letting unbound do the chroot & uid/gid changes. The upstream unit configuration this is based on is a lot stricter with all kinds of permissions then our previous variant. It also came with the default of having the `Type` set to `notify`, therefore we are also using the `unbound-with-systemd` package here. Unbound will start up, read the configuration files and start listening on the configured ports before systemd will declare the unit "running". This will likely help with startup order and the occasional race condition during system activation where the DNS service is started but not yet ready to answer queries. Aditionally to the much stricter runtime environmet I removed the `/dev/urandom` mount lines we previously had in the code (that would randomly fail during `stop`-phase). The `preStart` script is now only required if we enabled the trust anchor updates (which are still enabled by default). Another beneefit of the refactoring is that we can now issue reloads via either `pkill -HUP unbound` or `systemctl reload unbound` to reload the running configuration without taking the daemon offline. A prerequisite of this was that unbound configuration is available on a well known path on the file system. I went for /etc/unbound/unbound.conf as that is the default in the CLI tooling which in turn enables us to use `unbound-control` without passing a custom configuration location.
2020-05-07 11:17:14 +00:00
ExecStart = "${cfg.package}/bin/unbound -p -d -c /etc/unbound/unbound.conf";
ExecReload = "+/run/current-system/sw/bin/kill -HUP $MAINPID";
nixos/modules/services/networking/unbound: update systemd unit Previously we just applied a very minimal set of restrictions and trusted unbound to properly drop root privs and capabilities. With this change I am (for the most part) just using the upstream example unit file for unbound. The main difference is that we start unbound was `unbound` user with the required capabilities instead of letting unbound do the chroot & uid/gid changes. The upstream unit configuration this is based on is a lot stricter with all kinds of permissions then our previous variant. It also came with the default of having the `Type` set to `notify`, therefore we are also using the `unbound-with-systemd` package here. Unbound will start up, read the configuration files and start listening on the configured ports before systemd will declare the unit "running". This will likely help with startup order and the occasional race condition during system activation where the DNS service is started but not yet ready to answer queries. Aditionally to the much stricter runtime environmet I removed the `/dev/urandom` mount lines we previously had in the code (that would randomly fail during `stop`-phase). The `preStart` script is now only required if we enabled the trust anchor updates (which are still enabled by default). Another beneefit of the refactoring is that we can now issue reloads via either `pkill -HUP unbound` or `systemctl reload unbound` to reload the running configuration without taking the daemon offline. A prerequisite of this was that unbound configuration is available on a well known path on the file system. I went for /etc/unbound/unbound.conf as that is the default in the CLI tooling which in turn enables us to use `unbound-control` without passing a custom configuration location.
2020-05-07 11:17:14 +00:00
NotifyAccess = "main";
Type = "notify";
AmbientCapabilities = [
"CAP_NET_BIND_SERVICE"
"CAP_NET_RAW"
"CAP_SETGID"
"CAP_SETUID"
"CAP_SYS_CHROOT"
"CAP_SYS_RESOURCE"
];
User = "unbound";
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
nixos/modules/services/networking/unbound: update systemd unit Previously we just applied a very minimal set of restrictions and trusted unbound to properly drop root privs and capabilities. With this change I am (for the most part) just using the upstream example unit file for unbound. The main difference is that we start unbound was `unbound` user with the required capabilities instead of letting unbound do the chroot & uid/gid changes. The upstream unit configuration this is based on is a lot stricter with all kinds of permissions then our previous variant. It also came with the default of having the `Type` set to `notify`, therefore we are also using the `unbound-with-systemd` package here. Unbound will start up, read the configuration files and start listening on the configured ports before systemd will declare the unit "running". This will likely help with startup order and the occasional race condition during system activation where the DNS service is started but not yet ready to answer queries. Aditionally to the much stricter runtime environmet I removed the `/dev/urandom` mount lines we previously had in the code (that would randomly fail during `stop`-phase). The `preStart` script is now only required if we enabled the trust anchor updates (which are still enabled by default). Another beneefit of the refactoring is that we can now issue reloads via either `pkill -HUP unbound` or `systemctl reload unbound` to reload the running configuration without taking the daemon offline. A prerequisite of this was that unbound configuration is available on a well known path on the file system. I went for /etc/unbound/unbound.conf as that is the default in the CLI tooling which in turn enables us to use `unbound-control` without passing a custom configuration location.
2020-05-07 11:17:14 +00:00
PrivateTmp = true;
ProtectHome = true;
ProtectControlGroups = true;
ProtectKernelModules = true;
ProtectSystem = "strict";
RuntimeDirectory = "unbound";
ConfigurationDirectory = "unbound";
StateDirectory = "unbound";
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ];
RestrictRealtime = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"~@clock"
"@cpu-emulation"
"@debug"
"@keyring"
"@module"
"mount"
"@obsolete"
"@resources"
];
RestrictNamespaces = true;
LockPersonality = true;
RestrictSUIDSGID = true;
ReadWritePaths = [ "/run/unbound" "${stateDir}" ];
2014-08-27 01:24:09 +00:00
};
};
# If networkmanager is enabled, ask it to interface with unbound.
networking.networkmanager.dns = "unbound";
};
}