Merge pull request #62955 from abbradar/resolvconf
resolvconf service: init
This commit is contained in:
commit
294751a4fc
13 changed files with 216 additions and 145 deletions
|
@ -7,16 +7,6 @@ with lib;
|
|||
let
|
||||
|
||||
cfg = config.networking;
|
||||
dnsmasqResolve = config.services.dnsmasq.enable &&
|
||||
config.services.dnsmasq.resolveLocalQueries;
|
||||
hasLocalResolver = config.services.bind.enable ||
|
||||
config.services.unbound.enable ||
|
||||
dnsmasqResolve;
|
||||
|
||||
resolvconfOptions = cfg.resolvconfOptions
|
||||
++ optional cfg.dnsSingleRequest "single-request"
|
||||
++ optional cfg.dnsExtensionMechanism "edns0";
|
||||
|
||||
|
||||
localhostMapped4 = cfg.hosts ? "127.0.0.1" && elem "localhost" cfg.hosts."127.0.0.1";
|
||||
localhostMapped6 = cfg.hosts ? "::1" && elem "localhost" cfg.hosts."::1";
|
||||
|
@ -64,48 +54,6 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
networking.dnsSingleRequest = lib.mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Recent versions of glibc will issue both ipv4 (A) and ipv6 (AAAA)
|
||||
address queries at the same time, from the same port. Sometimes upstream
|
||||
routers will systemically drop the ipv4 queries. The symptom of this problem is
|
||||
that 'getent hosts example.com' only returns ipv6 (or perhaps only ipv4) addresses. The
|
||||
workaround for this is to specify the option 'single-request' in
|
||||
/etc/resolv.conf. This option enables that.
|
||||
'';
|
||||
};
|
||||
|
||||
networking.dnsExtensionMechanism = lib.mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enable the <code>edns0</code> option in <filename>resolv.conf</filename>. With
|
||||
that option set, <code>glibc</code> supports use of the extension mechanisms for
|
||||
DNS (EDNS) specified in RFC 2671. The most popular user of that feature is DNSSEC,
|
||||
which does not work without it.
|
||||
'';
|
||||
};
|
||||
|
||||
networking.extraResolvconfConf = lib.mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = "libc=NO";
|
||||
description = ''
|
||||
Extra configuration to append to <filename>resolvconf.conf</filename>.
|
||||
'';
|
||||
};
|
||||
|
||||
networking.resolvconfOptions = lib.mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "ndots:1" "rotate" ];
|
||||
description = ''
|
||||
Set the options in <filename>/etc/resolv.conf</filename>.
|
||||
'';
|
||||
};
|
||||
|
||||
networking.timeServers = mkOption {
|
||||
default = [
|
||||
"0.nixos.pool.ntp.org"
|
||||
|
@ -240,35 +188,6 @@ in
|
|||
# /etc/host.conf: resolver configuration file
|
||||
"host.conf".text = cfg.hostConf;
|
||||
|
||||
# /etc/resolvconf.conf: Configuration for openresolv.
|
||||
"resolvconf.conf".text =
|
||||
''
|
||||
# This is the default, but we must set it here to prevent
|
||||
# a collision with an apparently unrelated environment
|
||||
# variable with the same name exported by dhcpcd.
|
||||
interface_order='lo lo[0-9]*'
|
||||
'' + optionalString config.services.nscd.enable ''
|
||||
# Invalidate the nscd cache whenever resolv.conf is
|
||||
# regenerated.
|
||||
libc_restart='${pkgs.systemd}/bin/systemctl try-restart --no-block nscd.service 2> /dev/null'
|
||||
'' + optionalString (length resolvconfOptions > 0) ''
|
||||
# Options as described in resolv.conf(5)
|
||||
resolv_conf_options='${concatStringsSep " " resolvconfOptions}'
|
||||
'' + optionalString hasLocalResolver ''
|
||||
# This hosts runs a full-blown DNS resolver.
|
||||
name_servers='127.0.0.1'
|
||||
'' + optionalString dnsmasqResolve ''
|
||||
dnsmasq_conf=/etc/dnsmasq-conf.conf
|
||||
dnsmasq_resolv=/etc/dnsmasq-resolv.conf
|
||||
'' + cfg.extraResolvconfConf + ''
|
||||
'';
|
||||
|
||||
} // optionalAttrs config.services.resolved.enable {
|
||||
# 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 (config.services.resolved.enable && dnsmasqResolve) {
|
||||
"dnsmasq-resolv.conf".source = "/run/systemd/resolve/resolv.conf";
|
||||
} // optionalAttrs (pkgs.stdenv.hostPlatform.libc == "glibc") {
|
||||
# /etc/rpc: RPC program numbers.
|
||||
"rpc".source = pkgs.glibc.out + "/etc/rpc";
|
||||
|
@ -295,29 +214,6 @@ in
|
|||
# Install the proxy environment variables
|
||||
environment.sessionVariables = cfg.proxy.envVars;
|
||||
|
||||
# This is needed when /etc/resolv.conf is being overriden by networkd
|
||||
# and other configurations. If the file is destroyed by an environment
|
||||
# activation then it must be rebuilt so that applications which interface
|
||||
# with /etc/resolv.conf directly don't break.
|
||||
system.activationScripts.resolvconf = stringAfter [ "etc" "specialfs" "var" ]
|
||||
''
|
||||
# Systemd resolved controls its own resolv.conf
|
||||
rm -f /run/resolvconf/interfaces/systemd
|
||||
${optionalString config.services.resolved.enable ''
|
||||
rm -rf /run/resolvconf/interfaces
|
||||
mkdir -p /run/resolvconf/interfaces
|
||||
ln -s /run/systemd/resolve/resolv.conf /run/resolvconf/interfaces/systemd
|
||||
''}
|
||||
|
||||
# Make sure resolv.conf is up to date if not managed manually, by systemd or
|
||||
# by NetworkManager
|
||||
${optionalString (!config.environment.etc?"resolv.conf" &&
|
||||
(cfg.networkmanager.enable ->
|
||||
cfg.networkmanager.rc-manager == "resolvconf")) ''
|
||||
${pkgs.openresolv}/bin/resolvconf -u
|
||||
''}
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
149
nixos/modules/config/resolvconf.nix
Normal file
149
nixos/modules/config/resolvconf.nix
Normal file
|
@ -0,0 +1,149 @@
|
|||
# /etc files related to networking, such as /etc/services.
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.networking.resolvconf;
|
||||
|
||||
resolvconfOptions = cfg.extraOptions
|
||||
++ optional cfg.dnsSingleRequest "single-request"
|
||||
++ optional cfg.dnsExtensionMechanism "edns0";
|
||||
|
||||
configText =
|
||||
''
|
||||
# This is the default, but we must set it here to prevent
|
||||
# a collision with an apparently unrelated environment
|
||||
# variable with the same name exported by dhcpcd.
|
||||
interface_order='lo lo[0-9]*'
|
||||
'' + optionalString config.services.nscd.enable ''
|
||||
# Invalidate the nscd cache whenever resolv.conf is
|
||||
# regenerated.
|
||||
libc_restart='${pkgs.systemd}/bin/systemctl try-restart --no-block nscd.service 2> /dev/null'
|
||||
'' + optionalString (length resolvconfOptions > 0) ''
|
||||
# Options as described in resolv.conf(5)
|
||||
resolv_conf_options='${concatStringsSep " " resolvconfOptions}'
|
||||
'' + optionalString cfg.useLocalResolver ''
|
||||
# This hosts runs a full-blown DNS resolver.
|
||||
name_servers='127.0.0.1'
|
||||
'' + cfg.extraConfig;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
options = {
|
||||
|
||||
networking.resolvconf = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
internal = true;
|
||||
description = ''
|
||||
DNS configuration is managed by resolvconf.
|
||||
'';
|
||||
};
|
||||
|
||||
useHostResolvConf = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
In containers, whether to use the
|
||||
<filename>resolv.conf</filename> supplied by the host.
|
||||
'';
|
||||
};
|
||||
|
||||
dnsSingleRequest = lib.mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Recent versions of glibc will issue both ipv4 (A) and ipv6 (AAAA)
|
||||
address queries at the same time, from the same port. Sometimes upstream
|
||||
routers will systemically drop the ipv4 queries. The symptom of this problem is
|
||||
that 'getent hosts example.com' only returns ipv6 (or perhaps only ipv4) addresses. The
|
||||
workaround for this is to specify the option 'single-request' in
|
||||
/etc/resolv.conf. This option enables that.
|
||||
'';
|
||||
};
|
||||
|
||||
dnsExtensionMechanism = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enable the <code>edns0</code> option in <filename>resolv.conf</filename>. With
|
||||
that option set, <code>glibc</code> supports use of the extension mechanisms for
|
||||
DNS (EDNS) specified in RFC 2671. The most popular user of that feature is DNSSEC,
|
||||
which does not work without it.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = "libc=NO";
|
||||
description = ''
|
||||
Extra configuration to append to <filename>resolvconf.conf</filename>.
|
||||
'';
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "ndots:1" "rotate" ];
|
||||
description = ''
|
||||
Set the options in <filename>/etc/resolv.conf</filename>.
|
||||
'';
|
||||
};
|
||||
|
||||
useLocalResolver = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Use local DNS server for resolving.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
{
|
||||
networking.resolvconf.enable = !(config.environment.etc ? "resolv.conf");
|
||||
|
||||
environment.etc."resolvconf.conf".text =
|
||||
if !cfg.enable then
|
||||
# Force-stop any attempts to use resolvconf
|
||||
''
|
||||
echo "resolvconf is disabled on this system but was used anyway:" >&2
|
||||
echo "$0 $*" >&2
|
||||
exit 1
|
||||
''
|
||||
else configText;
|
||||
}
|
||||
|
||||
(mkIf cfg.enable {
|
||||
environment.systemPackages = [ pkgs.openresolv ];
|
||||
|
||||
systemd.services.resolvconf = {
|
||||
description = "resolvconf update";
|
||||
|
||||
before = [ "network-pre.target" ];
|
||||
wants = [ "network-pre.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
restartTriggers = [ config.environment.etc."resolvconf.conf".source ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${pkgs.openresolv}/bin/resolvconf -u";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
};
|
||||
|
||||
})
|
||||
];
|
||||
|
||||
}
|
|
@ -25,6 +25,7 @@
|
|||
./config/nsswitch.nix
|
||||
./config/power-management.nix
|
||||
./config/pulseaudio.nix
|
||||
./config/resolvconf.nix
|
||||
./config/shells-environment.nix
|
||||
./config/swap.nix
|
||||
./config/sysctl.nix
|
||||
|
|
|
@ -248,6 +248,12 @@ with lib;
|
|||
# KSM
|
||||
(mkRenamedOptionModule [ "hardware" "enableKSM" ] [ "hardware" "ksm" "enable" ])
|
||||
|
||||
# resolvconf
|
||||
(mkRenamedOptionModule [ "networking" "dnsSingleRequest" ] [ "networking" "resolvconf" "dnsSingleRequest" ])
|
||||
(mkRenamedOptionModule [ "networking" "dnsExtensionMechanism" ] [ "networking" "resolvconf" "dnsExtensionMechanism" ])
|
||||
(mkRenamedOptionModule [ "networking" "extraResolvconfConf" ] [ "networking" "resolvconf" "extraConfig" ])
|
||||
(mkRenamedOptionModule [ "networking" "resolvconfOptions" ] [ "networking" "resolvconf" "extraOptions" ])
|
||||
|
||||
] ++ (flip map [ "blackboxExporter" "collectdExporter" "fritzboxExporter"
|
||||
"jsonExporter" "minioExporter" "nginxExporter" "nodeExporter"
|
||||
"snmpExporter" "unifiExporter" "varnishExporter" ]
|
||||
|
|
|
@ -168,7 +168,9 @@ in
|
|||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.bind.enable {
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
networking.resolvconf.useLocalResolver = mkDefault true;
|
||||
|
||||
users.users = singleton
|
||||
{ name = bindUser;
|
||||
|
|
|
@ -79,7 +79,7 @@ in
|
|||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.dnsmasq.enable {
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
networking.nameservers =
|
||||
optional cfg.resolveLocalQueries "127.0.0.1";
|
||||
|
@ -92,6 +92,15 @@ in
|
|||
description = "Dnsmasq daemon user";
|
||||
};
|
||||
|
||||
networking.resolvconf = mkIf cfg.resolveLocalQueries {
|
||||
useLocalResolver = mkDefault true;
|
||||
|
||||
extraConfig = ''
|
||||
dnsmasq_conf=/etc/dnsmasq-conf.conf
|
||||
dnsmasq_resolv=/etc/dnsmasq-resolv.conf
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.dnsmasq = {
|
||||
description = "Dnsmasq Daemon";
|
||||
after = [ "network.target" "systemd-resolved.service" ];
|
||||
|
|
|
@ -16,7 +16,8 @@ let
|
|||
plugins=keyfile
|
||||
dhcp=${cfg.dhcp}
|
||||
dns=${cfg.dns}
|
||||
rc-manager=${cfg.rc-manager}
|
||||
# If resolvconf is disabled that means that resolv.conf is managed by some other module.
|
||||
rc-manager=${if config.networking.resolvconf.enable then "resolvconf" else "unmanaged"}
|
||||
|
||||
[keyfile]
|
||||
${optionalString (cfg.unmanaged != [])
|
||||
|
@ -268,25 +269,6 @@ in {
|
|||
'';
|
||||
};
|
||||
|
||||
rc-manager = mkOption {
|
||||
type = types.enum [ "symlink" "file" "resolvconf" "netconfig" "unmanaged" "none" ];
|
||||
default = "resolvconf";
|
||||
description = ''
|
||||
Set the <literal>resolv.conf</literal> management mode.
|
||||
</para>
|
||||
<para>
|
||||
A description of these modes can be found in the main section of
|
||||
<link xlink:href="https://developer.gnome.org/NetworkManager/stable/NetworkManager.conf.html">
|
||||
https://developer.gnome.org/NetworkManager/stable/NetworkManager.conf.html
|
||||
</link>
|
||||
or in
|
||||
<citerefentry>
|
||||
<refentrytitle>NetworkManager.conf</refentrytitle>
|
||||
<manvolnum>5</manvolnum>
|
||||
</citerefentry>.
|
||||
'';
|
||||
};
|
||||
|
||||
dispatcherScripts = mkOption {
|
||||
type = types.listOf (types.submodule {
|
||||
options = {
|
||||
|
@ -513,7 +495,7 @@ in {
|
|||
networking = {
|
||||
useDHCP = false;
|
||||
# use mkDefault to trigger the assertion about the conflict above
|
||||
wireless.enable = lib.mkDefault false;
|
||||
wireless.enable = mkDefault false;
|
||||
};
|
||||
|
||||
security.polkit.extraConfig = polkitConf;
|
||||
|
|
|
@ -35,6 +35,11 @@ in
|
|||
|
||||
config = mkIf config.services.rdnssd.enable {
|
||||
|
||||
assertions = [{
|
||||
assertion = config.networking.resolvconf.enable;
|
||||
message = "rdnssd needs resolvconf to work (probably something sets up a static resolv.conf)";
|
||||
}];
|
||||
|
||||
systemd.services.rdnssd = {
|
||||
description = "RDNSS daemon";
|
||||
after = [ "network.target" ];
|
||||
|
|
|
@ -101,6 +101,8 @@ in
|
|||
isSystemUser = true;
|
||||
};
|
||||
|
||||
networking.resolvconf.useLocalResolver = mkDefault true;
|
||||
|
||||
systemd.services.unbound = {
|
||||
description = "Unbound recursive Domain Name Server";
|
||||
after = [ "network.target" ];
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
with lib;
|
||||
let
|
||||
cfg = config.services.resolved;
|
||||
|
||||
dnsmasqResolve = config.services.dnsmasq.enable &&
|
||||
config.services.dnsmasq.resolveLocalQueries;
|
||||
|
||||
in
|
||||
{
|
||||
|
||||
|
@ -126,6 +130,12 @@ in
|
|||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
assertions = [
|
||||
{ assertion = !config.networking.useHostResolvConf;
|
||||
message = "Using host resolv.conf is not supported with systemd-resolved";
|
||||
}
|
||||
];
|
||||
|
||||
systemd.additionalUpstreamSystemUnits = [
|
||||
"systemd-resolved.service"
|
||||
];
|
||||
|
@ -135,21 +145,30 @@ in
|
|||
restartTriggers = [ config.environment.etc."systemd/resolved.conf".source ];
|
||||
};
|
||||
|
||||
environment.etc."systemd/resolved.conf".text = ''
|
||||
[Resolve]
|
||||
${optionalString (config.networking.nameservers != [])
|
||||
"DNS=${concatStringsSep " " config.networking.nameservers}"}
|
||||
${optionalString (cfg.fallbackDns != [])
|
||||
"FallbackDNS=${concatStringsSep " " cfg.fallbackDns}"}
|
||||
${optionalString (cfg.domains != [])
|
||||
"Domains=${concatStringsSep " " cfg.domains}"}
|
||||
LLMNR=${cfg.llmnr}
|
||||
DNSSEC=${cfg.dnssec}
|
||||
${config.services.resolved.extraConfig}
|
||||
'';
|
||||
environment.etc = {
|
||||
"systemd/resolved.conf".text = ''
|
||||
[Resolve]
|
||||
${optionalString (config.networking.nameservers != [])
|
||||
"DNS=${concatStringsSep " " config.networking.nameservers}"}
|
||||
${optionalString (cfg.fallbackDns != [])
|
||||
"FallbackDNS=${concatStringsSep " " cfg.fallbackDns}"}
|
||||
${optionalString (cfg.domains != [])
|
||||
"Domains=${concatStringsSep " " cfg.domains}"}
|
||||
LLMNR=${cfg.llmnr}
|
||||
DNSSEC=${cfg.dnssec}
|
||||
${config.services.resolved.extraConfig}
|
||||
'';
|
||||
|
||||
# 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";
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -4,19 +4,20 @@ with lib;
|
|||
|
||||
let
|
||||
|
||||
useHostResolvConf = config.networking.resolvconf.enable && config.networking.useHostResolvConf;
|
||||
|
||||
bootStage2 = pkgs.substituteAll {
|
||||
src = ./stage-2-init.sh;
|
||||
shellDebug = "${pkgs.bashInteractive}/bin/bash";
|
||||
shell = "${pkgs.bash}/bin/bash";
|
||||
isExecutable = true;
|
||||
inherit (config.nix) readOnlyStore;
|
||||
inherit (config.networking) useHostResolvConf;
|
||||
inherit useHostResolvConf;
|
||||
inherit (config.system.build) earlyMountScript;
|
||||
path = lib.makeBinPath [
|
||||
path = lib.makeBinPath ([
|
||||
pkgs.coreutils
|
||||
pkgs.utillinux
|
||||
pkgs.openresolv
|
||||
];
|
||||
] ++ lib.optional useHostResolvConf pkgs.openresolv);
|
||||
fsPackagesPath = lib.makeBinPath config.system.fsPackages;
|
||||
postBootCommands = pkgs.writeText "local-cmds"
|
||||
''
|
||||
|
|
|
@ -103,7 +103,7 @@ let
|
|||
|
||||
script =
|
||||
''
|
||||
${optionalString (!config.environment.etc?"resolv.conf") ''
|
||||
${optionalString config.networking.resolvconf.enable ''
|
||||
# Set the static DNS configuration, if given.
|
||||
${pkgs.openresolv}/sbin/resolvconf -m 1 -a static <<EOF
|
||||
${optionalString (cfg.nameservers != [] && cfg.domain != null) ''
|
||||
|
|
|
@ -1017,7 +1017,6 @@ in
|
|||
pkgs.iproute
|
||||
pkgs.iputils
|
||||
pkgs.nettools
|
||||
pkgs.openresolv
|
||||
]
|
||||
++ optionals config.networking.wireless.enable [
|
||||
pkgs.wirelesstools # FIXME: obsolete?
|
||||
|
|
Loading…
Reference in a new issue