2017-01-25 18:41:52 +01:00
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
|
|
|
|
|
|
|
cfg = config.services.kresd;
|
|
|
|
package = pkgs.knot-resolver;
|
|
|
|
|
|
|
|
configFile = pkgs.writeText "kresd.conf" cfg.extraConfig;
|
|
|
|
in
|
|
|
|
|
|
|
|
{
|
|
|
|
meta.maintainers = [ maintainers.vcunat /* upstream developer */ ];
|
|
|
|
|
|
|
|
###### interface
|
|
|
|
options.services.kresd = {
|
|
|
|
enable = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = ''
|
|
|
|
Whether to enable knot-resolver domain name server.
|
|
|
|
DNSSEC validation is turned on by default.
|
|
|
|
You can run <literal>sudo nc -U /run/kresd/control</literal>
|
|
|
|
and give commands interactively to kresd.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
extraConfig = mkOption {
|
|
|
|
type = types.lines;
|
|
|
|
default = "";
|
|
|
|
description = ''
|
|
|
|
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.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
interfaces = mkOption {
|
|
|
|
type = with types; listOf str;
|
|
|
|
default = [ "::1" "127.0.0.1" ];
|
|
|
|
description = ''
|
2018-02-01 17:15:28 +01:00
|
|
|
What addresses the server should listen on. (UDP+TCP 53)
|
2017-01-25 18:41:52 +01:00
|
|
|
'';
|
|
|
|
};
|
2018-02-12 20:48:25 +01:00
|
|
|
listenTLS = mkOption {
|
|
|
|
type = with types; listOf str;
|
|
|
|
default = [];
|
|
|
|
example = [ "198.51.100.1:853" "[2001:db8::1]:853" "853" ];
|
|
|
|
description = ''
|
|
|
|
Addresses on which kresd should provide DNS over TLS (see RFC 7858).
|
|
|
|
For detailed syntax see ListenStream in man systemd.socket.
|
|
|
|
'';
|
|
|
|
};
|
2017-01-25 18:41:52 +01:00
|
|
|
# TODO: perhaps options for more common stuff like cache size or forwarding
|
|
|
|
};
|
|
|
|
|
|
|
|
###### implementation
|
|
|
|
config = mkIf cfg.enable {
|
|
|
|
environment.etc."kresd.conf".source = configFile; # not required
|
|
|
|
|
2018-06-30 01:58:35 +02:00
|
|
|
users.users = singleton
|
2017-01-25 18:41:52 +01:00
|
|
|
{ name = "kresd";
|
|
|
|
uid = config.ids.uids.kresd;
|
|
|
|
group = "kresd";
|
|
|
|
description = "Knot-resolver daemon user";
|
|
|
|
};
|
2018-06-30 01:58:35 +02:00
|
|
|
users.groups = singleton
|
2017-01-25 18:41:52 +01:00
|
|
|
{ name = "kresd";
|
|
|
|
gid = config.ids.gids.kresd;
|
|
|
|
};
|
|
|
|
|
|
|
|
systemd.sockets.kresd = rec {
|
|
|
|
wantedBy = [ "sockets.target" ];
|
|
|
|
before = wantedBy;
|
|
|
|
listenStreams = map
|
|
|
|
# Syntax depends on being IPv6 or IPv4.
|
|
|
|
(iface: if elem ":" (stringToCharacters iface) then "[${iface}]:53" else "${iface}:53")
|
|
|
|
cfg.interfaces;
|
|
|
|
socketConfig.ListenDatagram = listenStreams;
|
2018-01-09 17:19:13 +01:00
|
|
|
socketConfig.FreeBind = true;
|
2017-01-25 18:41:52 +01:00
|
|
|
};
|
|
|
|
|
2018-02-12 20:48:25 +01:00
|
|
|
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";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2017-01-25 18:41:52 +01:00
|
|
|
systemd.sockets.kresd-control = rec {
|
|
|
|
wantedBy = [ "sockets.target" ];
|
|
|
|
before = wantedBy;
|
|
|
|
partOf = [ "kresd.socket" ];
|
|
|
|
listenStreams = [ "/run/kresd/control" ];
|
|
|
|
socketConfig = {
|
|
|
|
FileDescriptorName = "control";
|
|
|
|
Service = "kresd.service";
|
2018-01-09 17:19:13 +01:00
|
|
|
SocketMode = "0660"; # only root user/group may connect and control kresd
|
2017-01-25 18:41:52 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2018-01-09 17:11:36 +01:00
|
|
|
systemd.tmpfiles.rules = [ "d '${cfg.cacheDir}' 0770 kresd kresd - -" ];
|
2017-01-25 18:41:52 +01:00
|
|
|
|
|
|
|
systemd.services.kresd = {
|
|
|
|
description = "Knot-resolver daemon";
|
|
|
|
|
|
|
|
serviceConfig = {
|
|
|
|
User = "kresd";
|
|
|
|
Type = "notify";
|
|
|
|
WorkingDirectory = cfg.cacheDir;
|
2018-01-09 17:19:13 +01:00
|
|
|
Restart = "on-failure";
|
2018-02-12 20:48:25 +01:00
|
|
|
Sockets = [ "kresd.socket" "kresd-control.socket" ]
|
|
|
|
++ optional (cfg.listenTLS != []) "kresd-tls.socket";
|
2017-01-25 18:41:52 +01:00
|
|
|
};
|
|
|
|
|
2018-02-01 17:15:28 +01:00
|
|
|
# Trust anchor goes from dns-root-data by default.
|
2017-01-25 18:41:52 +01:00
|
|
|
script = ''
|
2018-02-01 17:15:28 +01:00
|
|
|
exec '${package}/bin/kresd' --config '${configFile}' --forks=1
|
2017-01-25 18:41:52 +01:00
|
|
|
'';
|
|
|
|
|
2018-01-09 17:11:36 +01:00
|
|
|
requires = [ "kresd.socket" ];
|
2017-01-25 18:41:52 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|