From b403014e4f87f1319ca52bb376ec692a135ff3d1 Mon Sep 17 00:00:00 2001 From: Lucas Savva Date: Tue, 17 Mar 2026 18:20:57 +0000 Subject: [PATCH] nixos/resolvconf: Enable by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #353225 The value of `networking.resolvconf.enable` was previously predicated on the existence `environment.etc."resolv.conf"`. This could lead to infinite recursion when an attribute defined within the resolvconf module was also required to define `environment.etc` (see example below). Instead, set the default to an explicit true and set the value to false where required in-tree. This turns out to only be two places: systemd-resolved and tetrd. Example infrec (from building .#nixosTests.containers-hosts): ``` … while evaluating definitions from `/nix/store/5djjm1dipmdh82issrmpfjdplp7hk0pp-source/nixos/modules/services/logging/logrotate.nix': … while evaluating the option `containers.netmask.services.logrotate.enable': … while evaluating the option `containers.netmask.users.groups': … while evaluating definitions from `/nix/store/5djjm1dipmdh82issrmpfjdplp7hk0pp-source/nixos/modules/config/resolvconf.nix': … while evaluating the option `containers.netmask.networking.resolvconf.enable': … while evaluating the option `containers.netmask.environment.etc': … while evaluating definitions from `/nix/store/5djjm1dipmdh82issrmpfjdplp7hk0pp-source/nixos/modules/services/logging/logrotate.nix': (stack trace truncated; use '--show-trace' to show the full, detailed trace) error: infinite recursion encountered at /nix/store/5djjm1dipmdh82issrmpfjdplp7hk0pp-source/lib/modules.nix:1512:13: 1511| _type = "if"; 1512| inherit condition content; | ^ 1513| }; ``` --- nixos/doc/manual/release-notes/rl-2605.section.md | 2 ++ nixos/modules/config/resolvconf.nix | 14 ++++++++++++-- nixos/modules/services/networking/tetrd.nix | 3 +++ nixos/modules/system/boot/resolved.nix | 4 ++++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/nixos/doc/manual/release-notes/rl-2605.section.md b/nixos/doc/manual/release-notes/rl-2605.section.md index f883372fd450..9b57f46a6557 100644 --- a/nixos/doc/manual/release-notes/rl-2605.section.md +++ b/nixos/doc/manual/release-notes/rl-2605.section.md @@ -356,6 +356,8 @@ See . - `systemd.network.*` has been updated to support all configuration options from upstream `networkd` version 259. +- `networking.resolvconf.enable` now defaults to `true` unconditionally instead of `!(config.environment.etc ? "resolv.conf")`.If you set `environment.etc."resolv.conf"` yourself, then you should also set `networking.resolvconf.enable = false`. + - `services.openssh` now supports generating host SSH keys by setting `services.openssh.generateHostKeys = true` while leaving `services.openssh.enable` disabled. This is particularly useful for systems that have no need of an SSH daemon but want SSH host keys for other purposes such as using agenix or sops-nix. - `services.openssh.enableRecommendedAlgorithms` has been added to allow users to opt out of NixOS's curated set of recommended algorithms. This set to true by default, and thus is not a breaking change. Users may want to set this to false if they prefer upstream's default algorithms. See . diff --git a/nixos/modules/config/resolvconf.nix b/nixos/modules/config/resolvconf.nix index e5831c0a71db..6b8a34f1a029 100644 --- a/nixos/modules/config/resolvconf.nix +++ b/nixos/modules/config/resolvconf.nix @@ -69,8 +69,7 @@ in enable = lib.mkOption { type = lib.types.bool; - default = !(config.environment.etc ? "resolv.conf"); - defaultText = lib.literalExpression ''!(config.environment.etc ? "resolv.conf")''; + default = true; description = '' Whether DNS configuration is managed by resolvconf. ''; @@ -170,6 +169,17 @@ in } (lib.mkIf cfg.enable { + assertions = [ + { + assertion = !(config.environment.etc ? "resolv.conf"); + message = '' + networking.resolvconf.enable is true but environment.etc."resolv.conf" + is also set. Set networking.resolvconf.enable = false if another + service manages /etc/resolv.conf. + ''; + } + ]; + users.groups.resolvconf = { }; networking.resolvconf.subscriberFiles = [ "/etc/resolv.conf" ]; diff --git a/nixos/modules/services/networking/tetrd.nix b/nixos/modules/services/networking/tetrd.nix index 939c1227886f..7b7b050bb0d7 100644 --- a/nixos/modules/services/networking/tetrd.nix +++ b/nixos/modules/services/networking/tetrd.nix @@ -14,6 +14,9 @@ etc."resolv.conf".source = "/etc/tetrd/resolv.conf"; }; + # Our resolv.conf will override resolvconf's version. + networking.resolvconf.enable = false; + systemd = { tmpfiles.rules = [ "f /etc/tetrd/resolv.conf - - -" ]; diff --git a/nixos/modules/system/boot/resolved.nix b/nixos/modules/system/boot/resolved.nix index 25569afdf78b..da2b57285a76 100644 --- a/nixos/modules/system/boot/resolved.nix +++ b/nixos/modules/system/boot/resolved.nix @@ -219,6 +219,10 @@ in # If networkmanager is enabled, ask it to interface with resolved. networking.networkmanager.dns = "systemd-resolved"; + # Since we explicitly provide a resolv.conf, disable resolvconf + networking.resolvconf.enable = false; + + # ... but we still set the package for correct compatibility. networking.resolvconf.package = config.systemd.package; nix.firewall.extraNftablesRules = [