diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index bedd87a368eb..979cdc5d4ad4 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -299,7 +299,7 @@ in
couchpotato = 267;
gogs = 268;
pdns-recursor = 269;
- kresd = 270;
+ #kresd = 270; # switched to "knot-resolver" with dynamic ID
rpc = 271;
geoip = 272;
fcron = 273;
@@ -600,7 +600,7 @@ in
headphones = 266;
couchpotato = 267;
gogs = 268;
- kresd = 270;
+ #kresd = 270; # switched to "knot-resolver" with dynamic ID
#rpc = 271; # unused
#geoip = 272; # unused
fcron = 273;
diff --git a/nixos/modules/services/networking/kresd.nix b/nixos/modules/services/networking/kresd.nix
index 3551e30c2e61..ce16b90b9cc1 100644
--- a/nixos/modules/services/networking/kresd.nix
+++ b/nixos/modules/services/networking/kresd.nix
@@ -3,12 +3,34 @@
with lib;
let
-
cfg = config.services.kresd;
- configFile = pkgs.writeText "kresd.conf" ''
- ${optionalString (cfg.listenDoH != []) "modules.load('http')"}
- ${cfg.extraConfig};
- '';
+
+ # Convert systemd-style address specification to kresd config line(s).
+ # On Nix level we don't attempt to precisely validate the address specifications.
+ mkListen = kind: addr: let
+ al_v4 = builtins.match "([0-9.]\+):([0-9]\+)" addr;
+ al_v6 = builtins.match "\\[(.\+)]:([0-9]\+)" addr;
+ al_portOnly = builtins.match "()([0-9]\+)" addr;
+ al = findFirst (a: a != null)
+ (throw "services.kresd.*: incorrect address specification '${addr}'")
+ [ al_v4 al_v6 al_portOnly ];
+ port = last al;
+ addrSpec = if al_portOnly == null then "'${head al}'" else "{'::', '127.0.0.1'}";
+ in # freebind is set for compatibility with earlier kresd services;
+ # it could be configurable, for example.
+ ''
+ net.listen(${addrSpec}, ${port}, { kind = '${kind}', freebind = true })
+ '';
+
+ configFile = pkgs.writeText "kresd.conf" (
+ optionalString (cfg.listenDoH != []) ''
+ modules.load('http')
+ ''
+ + concatMapStrings (mkListen "dns") cfg.listenPlain
+ + concatMapStrings (mkListen "tls") cfg.listenTLS
+ + concatMapStrings (mkListen "doh") cfg.listenDoH
+ + cfg.extraConfig
+ );
package = pkgs.knot-resolver.override {
extraFeatures = cfg.listenDoH != [];
@@ -25,6 +47,7 @@ in {
value
)
)
+ (mkRemovedOptionModule [ "services" "kresd" "cacheDir" ] "Please use (bind-)mounting instead.")
];
###### interface
@@ -35,8 +58,8 @@ in {
description = ''
Whether to enable knot-resolver domain name server.
DNSSEC validation is turned on by default.
- You can run sudo nc -U /run/kresd/control
- and give commands interactively to kresd.
+ You can run sudo nc -U /run/knot-resolver/control/1
+ and give commands interactively to kresd@1.service.
'';
};
extraConfig = mkOption {
@@ -46,16 +69,10 @@ in {
Extra lines to be added verbatim to the generated configuration file.
'';
};
- cacheDir = mkOption {
- type = types.path;
- default = "/var/cache/kresd";
- description = ''
- Directory for caches. They are intended to survive reboots.
- '';
- };
listenPlain = mkOption {
type = with types; listOf str;
default = [ "[::1]:53" "127.0.0.1:53" ];
+ example = [ "53" ];
description = ''
What addresses and ports the server should listen on.
For detailed syntax see ListenStream in man systemd.socket.
@@ -84,82 +101,35 @@ in {
###### implementation
config = mkIf cfg.enable {
- environment.etc."kresd.conf".source = configFile; # not required
+ environment.etc."knot-resolver/kresd.conf".source = configFile; # not required
- users.users.kresd =
- { uid = config.ids.uids.kresd;
- group = "kresd";
+ users.users.knot-resolver =
+ { isSystemUser = true;
+ group = "knot-resolver";
description = "Knot-resolver daemon user";
};
- users.groups.kresd.gid = config.ids.gids.kresd;
+ users.groups.knot-resolver.gid = null;
- systemd.sockets.kresd = rec {
- wantedBy = [ "sockets.target" ];
- before = wantedBy;
- listenStreams = cfg.listenPlain;
- socketConfig = {
- ListenDatagram = listenStreams;
- FreeBind = true;
- FileDescriptorName = "dns";
- };
+ systemd.packages = [ package ]; # the units are patched inside the package a bit
+
+ systemd.targets.kresd = {
+ wantedBy = [ "multi-user.target" ];
+ wants = [ "kres-cache-gc.service" "kresd@1.service" ];
+ };
+ systemd.services."kresd@".serviceConfig = {
+ ExecStart = "${package}/bin/kresd --noninteractive "
+ + "-c ${package}/lib/knot-resolver/distro-preconfig.lua -c ${configFile}";
+ # Ensure correct ownership in case UID or GID changes.
+ CacheDirectory = "knot-resolver";
+ CacheDirectoryMode = "0750";
};
- systemd.sockets.kresd-tls = mkIf (cfg.listenTLS != []) rec {
- wantedBy = [ "sockets.target" ];
- before = wantedBy;
- partOf = [ "kresd.socket" ];
- listenStreams = cfg.listenTLS;
- socketConfig = {
- FileDescriptorName = "tls";
- FreeBind = true;
- Service = "kresd.service";
- };
- };
+ environment.etc."tmpfiles.d/knot-resolver.conf".source =
+ "${package}/lib/tmpfiles.d/knot-resolver.conf";
- systemd.sockets.kresd-doh = mkIf (cfg.listenDoH != []) rec {
- wantedBy = [ "sockets.target" ];
- before = wantedBy;
- partOf = [ "kresd.socket" ];
- listenStreams = cfg.listenDoH;
- socketConfig = {
- FileDescriptorName = "doh";
- FreeBind = true;
- Service = "kresd.service";
- };
- };
-
- systemd.sockets.kresd-control = rec {
- wantedBy = [ "sockets.target" ];
- before = wantedBy;
- partOf = [ "kresd.socket" ];
- listenStreams = [ "/run/kresd/control" ];
- socketConfig = {
- FileDescriptorName = "control";
- Service = "kresd.service";
- SocketMode = "0660"; # only root user/group may connect and control kresd
- };
- };
-
- systemd.tmpfiles.rules = [ "d '${cfg.cacheDir}' 0770 kresd kresd - -" ];
-
- systemd.services.kresd = {
- description = "Knot-resolver daemon";
-
- serviceConfig = {
- User = "kresd";
- Type = "notify";
- WorkingDirectory = cfg.cacheDir;
- Restart = "on-failure";
- Sockets = [ "kresd.socket" "kresd-control.socket" ]
- ++ optional (cfg.listenTLS != []) "kresd-tls.socket";
- };
-
- # Trust anchor goes from dns-root-data by default.
- script = ''
- exec '${package}/bin/kresd' --config '${configFile}' --forks=1
- '';
-
- requires = [ "kresd.socket" ];
- };
+ # Try cleaning up the previously default location of cache file.
+ # Note that /var/cache/* should always be safe to remove.
+ # TODO: remove later, probably between 20.09 and 21.03
+ systemd.tmpfiles.rules = [ "R /var/cache/kresd" ];
};
}
diff --git a/pkgs/servers/dns/knot-resolver/default.nix b/pkgs/servers/dns/knot-resolver/default.nix
index 2dfb178b7ba1..29088e60153d 100644
--- a/pkgs/servers/dns/knot-resolver/default.nix
+++ b/pkgs/servers/dns/knot-resolver/default.nix
@@ -1,4 +1,4 @@
-{ stdenv, fetchurl
+{ stdenv, fetchurl, fetchpatch
# native deps.
, runCommand, pkgconfig, meson, ninja, makeWrapper
# build+runtime deps.
@@ -16,15 +16,38 @@ lua = luajitPackages;
unwrapped = stdenv.mkDerivation rec {
pname = "knot-resolver";
- version = "4.3.0";
+ version = "5.0.0";
src = fetchurl {
url = "https://secure.nic.cz/files/knot-resolver/${pname}-${version}.tar.xz";
- sha256 = "0ca0f171ae2b2d76830967a5150eb0fa496b48b2a48f41b2be65d3743aaece25";
+ sha256 = "ca6023cd0c18b11f4a0cff0c8e882c7f3a5ad6653e9aa95acdbedafc5a53a5ed";
};
outputs = [ "out" "dev" ];
+ patches = [
+ (fetchpatch { # TODO: included in the next release.
+ name = "fix-GC-path.patch";
+ url = "https://gitlab.labs.nic.cz/knot/knot-resolver/commit/b723dbbe0.diff";
+ sha256 = "1hrwbv9vjybnwm083jxcinzw3fmwlsf1dgxrly7mhjs8d3jhqc4z";
+ })
+ ];
+
+ # Path fixups for the NixOS service.
+ postPatch = ''
+ patch meson.build <