diff --git a/nixos/modules/config/networking.nix b/nixos/modules/config/networking.nix
index eab4e73e19a1..4b9086022ed5 100644
--- a/nixos/modules/config/networking.nix
+++ b/nixos/modules/config/networking.nix
@@ -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 edns0
option in resolv.conf. With
- that option set, glibc
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 resolvconf.conf.
- '';
- };
-
- networking.resolvconfOptions = lib.mkOption {
- type = types.listOf types.str;
- default = [];
- example = [ "ndots:1" "rotate" ];
- description = ''
- Set the options in /etc/resolv.conf.
- '';
- };
-
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
- ''}
- '';
-
};
}
diff --git a/nixos/modules/config/resolvconf.nix b/nixos/modules/config/resolvconf.nix
new file mode 100644
index 000000000000..406c6a7ac329
--- /dev/null
+++ b/nixos/modules/config/resolvconf.nix
@@ -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
+ resolv.conf 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 edns0
option in resolv.conf. With
+ that option set, glibc
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 resolvconf.conf.
+ '';
+ };
+
+ extraOptions = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ example = [ "ndots:1" "rotate" ];
+ description = ''
+ Set the options in /etc/resolv.conf.
+ '';
+ };
+
+ 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;
+ };
+ };
+
+ })
+ ];
+
+}
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 1d1995eda25a..ba9ea9d28248 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -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
diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix
index 1b77a895d717..ca8db9a1a48e 100644
--- a/nixos/modules/rename.nix
+++ b/nixos/modules/rename.nix
@@ -244,6 +244,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" ]
diff --git a/nixos/modules/services/networking/bind.nix b/nixos/modules/services/networking/bind.nix
index 7f89cff22329..2097b9a31639 100644
--- a/nixos/modules/services/networking/bind.nix
+++ b/nixos/modules/services/networking/bind.nix
@@ -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;
diff --git a/nixos/modules/services/networking/dnsmasq.nix b/nixos/modules/services/networking/dnsmasq.nix
index 24d16046c63e..714a5903bff1 100644
--- a/nixos/modules/services/networking/dnsmasq.nix
+++ b/nixos/modules/services/networking/dnsmasq.nix
@@ -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" ];
diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix
index f1f8c9722e02..49d46456c044 100644
--- a/nixos/modules/services/networking/networkmanager.nix
+++ b/nixos/modules/services/networking/networkmanager.nix
@@ -17,7 +17,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 resolv.conf management mode.
-
-
- A description of these modes can be found in the main section of
-
- https://developer.gnome.org/NetworkManager/stable/NetworkManager.conf.html
-
- or in
-
- NetworkManager.conf
- 5
- .
- '';
- };
-
dispatcherScripts = mkOption {
type = types.listOf (types.submodule {
options = {
@@ -512,7 +494,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;
diff --git a/nixos/modules/services/networking/rdnssd.nix b/nixos/modules/services/networking/rdnssd.nix
index 887772f6e5f0..bccab805beeb 100644
--- a/nixos/modules/services/networking/rdnssd.nix
+++ b/nixos/modules/services/networking/rdnssd.nix
@@ -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" ];
diff --git a/nixos/modules/services/networking/unbound.nix b/nixos/modules/services/networking/unbound.nix
index 1a35979ad44c..3cf82e8839bb 100644
--- a/nixos/modules/services/networking/unbound.nix
+++ b/nixos/modules/services/networking/unbound.nix
@@ -101,6 +101,8 @@ in
isSystemUser = true;
};
+ networking.resolvconf.useLocalResolver = mkDefault true;
+
systemd.services.unbound = {
description = "Unbound recursive Domain Name Server";
after = [ "network.target" ];
diff --git a/nixos/modules/system/boot/resolved.nix b/nixos/modules/system/boot/resolved.nix
index 5c66cf4a6e6e..3ea96f8e4645 100644
--- a/nixos/modules/system/boot/resolved.nix
+++ b/nixos/modules/system/boot/resolved.nix
@@ -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";
+
};
}
diff --git a/nixos/modules/system/boot/stage-2.nix b/nixos/modules/system/boot/stage-2.nix
index 55e6b19c67fd..6b0b47227301 100644
--- a/nixos/modules/system/boot/stage-2.nix
+++ b/nixos/modules/system/boot/stage-2.nix
@@ -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"
''
diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix
index c12ada7a030a..2b8a7944dc36 100644
--- a/nixos/modules/tasks/network-interfaces-scripted.nix
+++ b/nixos/modules/tasks/network-interfaces-scripted.nix
@@ -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 <