2022-03-29 21:14:13 +02:00
|
|
|
{
|
|
|
|
config,
|
|
|
|
lib,
|
|
|
|
pkgs,
|
|
|
|
...
|
|
|
|
}:
|
2015-04-19 21:05:12 +02:00
|
|
|
|
|
|
|
with lib;
|
2016-06-26 22:58:04 +02:00
|
|
|
let
|
|
|
|
cfg = config.services.resolved;
|
2019-07-15 20:18:49 +03:00
|
|
|
|
|
|
|
dnsmasqResolve = config.services.dnsmasq.enable && config.services.dnsmasq.resolveLocalQueries;
|
|
|
|
|
2024-04-07 21:18:59 -04:00
|
|
|
resolvedConf = ''
|
|
|
|
[Resolve]
|
|
|
|
${optionalString (
|
|
|
|
config.networking.nameservers != [ ]
|
|
|
|
) "DNS=${concatStringsSep " " config.networking.nameservers}"}
|
|
|
|
${optionalString (cfg.fallbackDns != null) "FallbackDNS=${concatStringsSep " " cfg.fallbackDns}"}
|
|
|
|
${optionalString (cfg.domains != [ ]) "Domains=${concatStringsSep " " cfg.domains}"}
|
|
|
|
LLMNR=${cfg.llmnr}
|
|
|
|
DNSSEC=${cfg.dnssec}
|
|
|
|
DNSOverTLS=${cfg.dnsovertls}
|
|
|
|
${config.services.resolved.extraConfig}
|
|
|
|
'';
|
|
|
|
|
2016-06-26 22:58:04 +02:00
|
|
|
in
|
2015-04-19 21:05:12 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
options = {
|
|
|
|
|
|
|
|
services.resolved.enable = mkOption {
|
|
|
|
default = false;
|
|
|
|
type = types.bool;
|
2022-07-19 15:05:45 +02:00
|
|
|
description = ''
|
2023-04-07 01:09:05 +02:00
|
|
|
Whether to enable the systemd DNS resolver daemon, `systemd-resolved`.
|
|
|
|
|
|
|
|
Search for `services.resolved` to see all options.
|
2015-04-19 21:05:12 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2016-06-26 22:58:04 +02:00
|
|
|
services.resolved.fallbackDns = mkOption {
|
2023-12-08 16:00:42 +00:00
|
|
|
default = null;
|
2016-06-26 22:58:04 +02:00
|
|
|
example = [
|
|
|
|
"8.8.8.8"
|
|
|
|
"2001:4860:4860::8844"
|
|
|
|
];
|
2023-12-08 16:00:42 +00:00
|
|
|
type = types.nullOr (types.listOf types.str);
|
2022-07-19 15:05:45 +02:00
|
|
|
description = ''
|
2016-06-26 22:58:04 +02:00
|
|
|
A list of IPv4 and IPv6 addresses to use as the fallback DNS servers.
|
2023-12-08 16:00:42 +00:00
|
|
|
If this option is null, a compiled-in list of DNS servers is used instead.
|
|
|
|
Setting this option to an empty list will override the built-in list to an empty list, disabling fallback.
|
2016-06-26 22:58:04 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
services.resolved.domains = mkOption {
|
|
|
|
default = config.networking.search;
|
|
|
|
defaultText = literalExpression "config.networking.search";
|
|
|
|
example = [ "example.com" ];
|
|
|
|
type = types.listOf types.str;
|
2022-07-19 15:05:45 +02:00
|
|
|
description = ''
|
2017-10-16 14:30:36 +02:00
|
|
|
A list of domains. These domains are used as search suffixes
|
|
|
|
when resolving single-label host names (domain names which
|
|
|
|
contain no dot), in order to qualify them into fully-qualified
|
|
|
|
domain names (FQDNs).
|
2019-05-13 09:15:17 +02:00
|
|
|
|
2017-10-16 14:30:36 +02:00
|
|
|
For compatibility reasons, if this setting is not specified,
|
|
|
|
the search domains listed in
|
2022-07-19 15:05:45 +02:00
|
|
|
{file}`/etc/resolv.conf` are used instead, if
|
2017-10-16 14:30:36 +02:00
|
|
|
that file exists and any domains are configured in it.
|
2016-06-26 22:58:04 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
services.resolved.llmnr = mkOption {
|
|
|
|
default = "true";
|
|
|
|
example = "false";
|
|
|
|
type = types.enum [
|
|
|
|
"true"
|
|
|
|
"resolve"
|
|
|
|
"false"
|
|
|
|
];
|
2022-07-19 15:05:45 +02:00
|
|
|
description = ''
|
2017-10-16 14:30:36 +02:00
|
|
|
Controls Link-Local Multicast Name Resolution support
|
|
|
|
(RFC 4795) on the local host.
|
2019-05-13 09:15:17 +02:00
|
|
|
|
2017-10-16 14:30:36 +02:00
|
|
|
If set to
|
2022-07-19 15:05:45 +02:00
|
|
|
- `"true"`: Enables full LLMNR responder and resolver support.
|
|
|
|
- `"false"`: Disables both.
|
|
|
|
- `"resolve"`: Only resolution support is enabled, but responding is disabled.
|
2016-06-26 22:58:04 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
services.resolved.dnssec = mkOption {
|
2023-09-13 11:49:16 +02:00
|
|
|
default = "false";
|
2016-06-26 22:58:04 +02:00
|
|
|
example = "true";
|
|
|
|
type = types.enum [
|
|
|
|
"true"
|
|
|
|
"allow-downgrade"
|
|
|
|
"false"
|
|
|
|
];
|
2022-07-19 15:05:45 +02:00
|
|
|
description = ''
|
2017-10-16 14:30:36 +02:00
|
|
|
If set to
|
2022-07-19 15:05:45 +02:00
|
|
|
- `"true"`:
|
2017-10-16 14:30:36 +02:00
|
|
|
all DNS lookups are DNSSEC-validated locally (excluding
|
|
|
|
LLMNR and Multicast DNS). Note that this mode requires a
|
|
|
|
DNS server that supports DNSSEC. If the DNS server does
|
|
|
|
not properly support DNSSEC all validations will fail.
|
2022-07-19 15:05:45 +02:00
|
|
|
- `"allow-downgrade"`:
|
2017-10-16 14:30:36 +02:00
|
|
|
DNSSEC validation is attempted, but if the server does not
|
|
|
|
support DNSSEC properly, DNSSEC mode is automatically
|
|
|
|
disabled. Note that this mode makes DNSSEC validation
|
|
|
|
vulnerable to "downgrade" attacks, where an attacker might
|
|
|
|
be able to trigger a downgrade to non-DNSSEC mode by
|
|
|
|
synthesizing a DNS response that suggests DNSSEC was not
|
|
|
|
supported.
|
2022-07-19 15:05:45 +02:00
|
|
|
- `"false"`: DNS lookups are not DNSSEC validated.
|
2023-09-13 11:49:16 +02:00
|
|
|
|
|
|
|
At the time of September 2023, systemd upstream advise
|
|
|
|
to disable DNSSEC by default as the current code
|
|
|
|
is not robust enough to deal with "in the wild" non-compliant
|
|
|
|
servers, which will usually give you a broken bad experience
|
|
|
|
in addition of insecure.
|
2016-06-26 22:58:04 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2024-01-14 20:35:02 -06:00
|
|
|
services.resolved.dnsovertls = mkOption {
|
|
|
|
default = "false";
|
|
|
|
example = "true";
|
|
|
|
type = types.enum [
|
|
|
|
"true"
|
|
|
|
"opportunistic"
|
|
|
|
"false"
|
|
|
|
];
|
|
|
|
description = ''
|
|
|
|
If set to
|
|
|
|
- `"true"`:
|
|
|
|
all DNS lookups will be encrypted. This requires
|
|
|
|
that the DNS server supports DNS-over-TLS and
|
|
|
|
has a valid certificate. If the hostname was specified
|
|
|
|
via the `address#hostname` format in {option}`services.resolved.domains`
|
|
|
|
then the specified hostname is used to validate its certificate.
|
|
|
|
- `"opportunistic"`:
|
|
|
|
all DNS lookups will attempt to be encrypted, but will fallback
|
|
|
|
to unecrypted requests if the server does not support DNS-over-TLS.
|
|
|
|
Note that this mode does allow for a malicious party to conduct a
|
|
|
|
downgrade attack by immitating the DNS server and pretending to not
|
|
|
|
support encryption.
|
|
|
|
- `"false"`:
|
|
|
|
all DNS lookups are done unencrypted.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2016-06-26 22:58:04 +02:00
|
|
|
services.resolved.extraConfig = mkOption {
|
|
|
|
default = "";
|
|
|
|
type = types.lines;
|
2022-07-19 15:05:45 +02:00
|
|
|
description = ''
|
2016-06-26 22:58:04 +02:00
|
|
|
Extra config to append to resolved.conf.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2024-04-07 21:18:59 -04:00
|
|
|
boot.initrd.services.resolved.enable = mkOption {
|
|
|
|
default = config.boot.initrd.systemd.network.enable;
|
|
|
|
defaultText = "config.boot.initrd.systemd.network.enable";
|
|
|
|
description = ''
|
|
|
|
Whether to enable resolved for stage 1 networking.
|
|
|
|
Uses the toplevel 'services.resolved' options for 'resolved.conf'
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2015-04-19 21:05:12 +02:00
|
|
|
};
|
|
|
|
|
2024-04-07 20:32:41 -04:00
|
|
|
config = mkMerge [
|
|
|
|
(mkIf cfg.enable {
|
|
|
|
|
|
|
|
assertions = [
|
|
|
|
{
|
|
|
|
assertion = !config.networking.useHostResolvConf;
|
|
|
|
message = "Using host resolv.conf is not supported with systemd-resolved";
|
|
|
|
}
|
|
|
|
];
|
|
|
|
|
|
|
|
users.users.systemd-resolve.group = "systemd-resolve";
|
|
|
|
|
|
|
|
# add resolve to nss hosts database if enabled and nscd enabled
|
|
|
|
# system.nssModules is configured in nixos/modules/system/boot/systemd.nix
|
|
|
|
# added with order 501 to allow modules to go before with mkBefore
|
|
|
|
system.nssDatabases.hosts = (mkOrder 501 [ "resolve [!UNAVAIL=return]" ]);
|
|
|
|
|
|
|
|
systemd.additionalUpstreamSystemUnits = [
|
|
|
|
"systemd-resolved.service"
|
|
|
|
];
|
|
|
|
|
|
|
|
systemd.services.systemd-resolved = {
|
2024-04-07 20:33:13 -04:00
|
|
|
wantedBy = [ "sysinit.target" ];
|
2024-04-07 20:32:41 -04:00
|
|
|
aliases = [ "dbus-org.freedesktop.resolve1.service" ];
|
2025-01-08 13:38:04 -05:00
|
|
|
reloadTriggers = [ config.environment.etc."systemd/resolved.conf".source ];
|
2025-01-08 12:59:33 -05:00
|
|
|
stopIfChanged = false;
|
2024-04-07 20:32:41 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
environment.etc =
|
|
|
|
{
|
2024-04-07 21:18:59 -04:00
|
|
|
"systemd/resolved.conf".text = resolvedConf;
|
2024-04-07 20:32:41 -04:00
|
|
|
|
|
|
|
# symlink the dynamic stub resolver of resolv.conf as recommended by upstream:
|
|
|
|
# https://www.freedesktop.org/software/systemd/man/systemd-resolved.html#/etc/resolv.conf
|
|
|
|
"resolv.conf".source = "/run/systemd/resolve/stub-resolv.conf";
|
|
|
|
}
|
|
|
|
// optionalAttrs dnsmasqResolve {
|
|
|
|
"dnsmasq-resolv.conf".source = "/run/systemd/resolve/resolv.conf";
|
|
|
|
};
|
|
|
|
|
|
|
|
# If networkmanager is enabled, ask it to interface with resolved.
|
|
|
|
networking.networkmanager.dns = "systemd-resolved";
|
|
|
|
|
|
|
|
networking.resolvconf.package = pkgs.systemd;
|
|
|
|
|
|
|
|
})
|
|
|
|
|
2024-04-07 21:18:59 -04:00
|
|
|
(mkIf config.boot.initrd.services.resolved.enable {
|
|
|
|
|
|
|
|
assertions = [
|
|
|
|
{
|
|
|
|
assertion = config.boot.initrd.systemd.enable;
|
|
|
|
message = "'boot.initrd.services.resolved.enable' can only be enabled with systemd stage 1.";
|
|
|
|
}
|
|
|
|
];
|
|
|
|
|
|
|
|
boot.initrd.systemd = {
|
|
|
|
contents = {
|
|
|
|
"/etc/systemd/resolved.conf".text = resolvedConf;
|
|
|
|
};
|
|
|
|
|
2024-09-04 11:35:44 +02:00
|
|
|
tmpfiles.settings.systemd-resolved-stub."/etc/resolv.conf".L.argument =
|
|
|
|
"/run/systemd/resolve/stub-resolv.conf";
|
|
|
|
|
2024-04-07 21:18:59 -04:00
|
|
|
additionalUpstreamUnits = [ "systemd-resolved.service" ];
|
|
|
|
users.systemd-resolve = { };
|
|
|
|
groups.systemd-resolve = { };
|
|
|
|
storePaths = [ "${config.boot.initrd.systemd.package}/lib/systemd/systemd-resolved" ];
|
|
|
|
services.systemd-resolved = {
|
|
|
|
wantedBy = [ "sysinit.target" ];
|
|
|
|
aliases = [ "dbus-org.freedesktop.resolve1.service" ];
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
})
|
2024-04-07 20:32:41 -04:00
|
|
|
];
|
2015-04-19 21:05:12 +02:00
|
|
|
|
|
|
|
}
|