From 146bffe5aa6c6f8ea7d280ca85f4cbf239fb9751 Mon Sep 17 00:00:00 2001 From: Will Fancher Date: Sun, 7 Apr 2024 20:32:41 -0400 Subject: [PATCH 1/6] nixos/systemd-resolved: Re-indent --- nixos/modules/system/boot/resolved.nix | 109 +++++++++++++------------ 1 file changed, 56 insertions(+), 53 deletions(-) diff --git a/nixos/modules/system/boot/resolved.nix b/nixos/modules/system/boot/resolved.nix index 64a15179438fe..6006ed7894c90 100644 --- a/nixos/modules/system/boot/resolved.nix +++ b/nixos/modules/system/boot/resolved.nix @@ -128,58 +128,61 @@ in }; - config = 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 = { - wantedBy = [ "multi-user.target" ]; - aliases = [ "dbus-org.freedesktop.resolve1.service" ]; - 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 != 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} - ''; - - # 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; - - }; + 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 = { + wantedBy = [ "multi-user.target" ]; + aliases = [ "dbus-org.freedesktop.resolve1.service" ]; + 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 != 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} + ''; + + # 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; + + }) + + ]; } From 154459858f661487e543ce5d1a2a3d37b9638da6 Mon Sep 17 00:00:00 2001 From: Will Fancher Date: Sun, 7 Apr 2024 20:33:13 -0400 Subject: [PATCH 2/6] nixos/systemd-resolved: Should be wanted by sysinit.target As per its [Install] section upstream --- nixos/modules/system/boot/resolved.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/system/boot/resolved.nix b/nixos/modules/system/boot/resolved.nix index 6006ed7894c90..2c9a7ddee4f6f 100644 --- a/nixos/modules/system/boot/resolved.nix +++ b/nixos/modules/system/boot/resolved.nix @@ -149,7 +149,7 @@ in ]; systemd.services.systemd-resolved = { - wantedBy = [ "multi-user.target" ]; + wantedBy = [ "sysinit.target" ]; aliases = [ "dbus-org.freedesktop.resolve1.service" ]; restartTriggers = [ config.environment.etc."systemd/resolved.conf".source ]; }; From 9231977e8649c5ce70e6924df98652538fa82e70 Mon Sep 17 00:00:00 2001 From: Will Fancher Date: Mon, 20 May 2024 19:37:01 -0400 Subject: [PATCH 3/6] nixos/tests: systemd-resolved --- nixos/tests/all-tests.nix | 1 + nixos/tests/systemd-resolved.nix | 60 ++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 nixos/tests/systemd-resolved.nix diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 10daa1bbf6d26..2b715a3568430 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -929,6 +929,7 @@ in { systemd-oomd = handleTest ./systemd-oomd.nix {}; systemd-portabled = handleTest ./systemd-portabled.nix {}; systemd-repart = handleTest ./systemd-repart.nix {}; + systemd-resolved = handleTest ./systemd-resolved.nix {}; systemd-shutdown = handleTest ./systemd-shutdown.nix {}; systemd-sysupdate = runTest ./systemd-sysupdate.nix; systemd-sysusers-mutable = runTest ./systemd-sysusers-mutable.nix; diff --git a/nixos/tests/systemd-resolved.nix b/nixos/tests/systemd-resolved.nix new file mode 100644 index 0000000000000..64630b3e99091 --- /dev/null +++ b/nixos/tests/systemd-resolved.nix @@ -0,0 +1,60 @@ +import ./make-test-python.nix ({ pkgs, lib, ... }: { + name = "systemd-resolved"; + meta.maintainers = [ lib.maintainers.elvishjerricco ]; + + nodes.server = { lib, config, ... }: let + exampleZone = pkgs.writeTextDir "example.com.zone" '' + @ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800 + @ A ${(lib.head config.networking.interfaces.eth1.ipv4.addresses).address} + @ AAAA ${(lib.head config.networking.interfaces.eth1.ipv6.addresses).address} + ''; + in { + networking.firewall.enable = false; + networking.useDHCP = false; + + networking.interfaces.eth1.ipv6.addresses = lib.mkForce [ + { address = "fd00::1"; prefixLength = 64; } + ]; + + services.knot = { + enable = true; + settings = { + server.listen = [ + "0.0.0.0@53" + "::@53" + ]; + template.default.storage = exampleZone; + zone."example.com".file = "example.com.zone"; + }; + }; + }; + + nodes.client = { nodes, ... }: let + inherit (lib.head nodes.server.networking.interfaces.eth1.ipv4.addresses) address; + in { + networking.nameservers = [ address ]; + networking.interfaces.eth1.ipv6.addresses = lib.mkForce [ + { address = "fd00::2"; prefixLength = 64; } + ]; + services.resolved.enable = true; + services.resolved.fallbackDns = [ ]; + networking.useNetworkd = true; + networking.useDHCP = false; + systemd.network.networks."40-eth0".enable = false; + }; + + testScript = { nodes, ... }: let + address4 = (lib.head nodes.server.networking.interfaces.eth1.ipv4.addresses).address; + address6 = (lib.head nodes.server.networking.interfaces.eth1.ipv6.addresses).address; + in '' + start_all() + server.wait_for_unit("multi-user.target") + client.wait_for_unit("multi-user.target") + + query = client.succeed("resolvectl query example.com") + assert "${address4}" in query + assert "${address6}" in query + client.succeed("ping -4 -c 1 example.com") + client.succeed("ping -6 -c 1 example.com") + ''; +}) From dd0ebdffcd90a9a1d33297f401a776c3b510509e Mon Sep 17 00:00:00 2001 From: Will Fancher Date: Tue, 21 May 2024 20:52:42 -0400 Subject: [PATCH 4/6] nixos/systemd-stage-1/dbus: Fix systemd services --- nixos/modules/services/system/dbus.nix | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nixos/modules/services/system/dbus.nix b/nixos/modules/services/system/dbus.nix index 26f4eba707f92..d84136125f934 100644 --- a/nixos/modules/services/system/dbus.nix +++ b/nixos/modules/services/system/dbus.nix @@ -128,10 +128,14 @@ in contents."/etc/dbus-1".source = pkgs.makeDBusConf { inherit (cfg) apparmor; suidHelper = "/bin/false"; - serviceDirectories = [ pkgs.dbus ]; + serviceDirectories = [ pkgs.dbus config.boot.initrd.systemd.package ]; }; packages = [ pkgs.dbus ]; - storePaths = [ "${pkgs.dbus}/bin/dbus-daemon" ]; + storePaths = [ + "${pkgs.dbus}/bin/dbus-daemon" + "${config.boot.initrd.systemd.package}/share/dbus-1/system-services" + "${config.boot.initrd.systemd.package}/share/dbus-1/system.d" + ]; targets.sockets.wants = [ "dbus.socket" ]; }; }) From 072054ccb5d8c73ee0cc75d37b3e5d16c33d2de4 Mon Sep 17 00:00:00 2001 From: Will Fancher Date: Sun, 7 Apr 2024 21:18:59 -0400 Subject: [PATCH 5/6] nixos/systemd-stage-1: Support systemd-resolved --- nixos/modules/system/boot/resolved.nix | 64 ++++++++++++++++++++------ 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/nixos/modules/system/boot/resolved.nix b/nixos/modules/system/boot/resolved.nix index 2c9a7ddee4f6f..b658a7a2dc05e 100644 --- a/nixos/modules/system/boot/resolved.nix +++ b/nixos/modules/system/boot/resolved.nix @@ -7,6 +7,20 @@ let dnsmasqResolve = config.services.dnsmasq.enable && config.services.dnsmasq.resolveLocalQueries; + 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} + ''; + in { @@ -126,6 +140,15 @@ in ''; }; + 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' + ''; + }; + }; config = mkMerge [ @@ -155,19 +178,7 @@ in }; environment.etc = { - "systemd/resolved.conf".text = '' - [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} - ''; + "systemd/resolved.conf".text = resolvedConf; # 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 @@ -183,6 +194,33 @@ in }) + (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/tmpfiles.d/resolv.conf".text = + "L /etc/resolv.conf - - - - /run/systemd/resolve/stub-resolv.conf"; + "/etc/systemd/resolved.conf".text = resolvedConf; + }; + + 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" ]; + }; + }; + + }) ]; } From bfdba4d0812c080fc5d4667377e5d4afee88ba88 Mon Sep 17 00:00:00 2001 From: Will Fancher Date: Tue, 21 May 2024 02:39:10 -0400 Subject: [PATCH 6/6] nixos/tests: systemd-resolved in stage 1 --- nixos/tests/systemd-resolved.nix | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/nixos/tests/systemd-resolved.nix b/nixos/tests/systemd-resolved.nix index 64630b3e99091..3eedc17f4b34f 100644 --- a/nixos/tests/systemd-resolved.nix +++ b/nixos/tests/systemd-resolved.nix @@ -41,6 +41,14 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { networking.useNetworkd = true; networking.useDHCP = false; systemd.network.networks."40-eth0".enable = false; + + testing.initrdBackdoor = true; + boot.initrd = { + systemd.enable = true; + systemd.initrdBin = [ pkgs.iputils ]; + network.enable = true; + services.resolved.enable = true; + }; }; testScript = { nodes, ... }: let @@ -49,12 +57,19 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { in '' start_all() server.wait_for_unit("multi-user.target") - client.wait_for_unit("multi-user.target") - query = client.succeed("resolvectl query example.com") - assert "${address4}" in query - assert "${address6}" in query - client.succeed("ping -4 -c 1 example.com") - client.succeed("ping -6 -c 1 example.com") + def test_client(): + query = client.succeed("resolvectl query example.com") + assert "${address4}" in query + assert "${address6}" in query + client.succeed("ping -4 -c 1 example.com") + client.succeed("ping -6 -c 1 example.com") + + client.wait_for_unit("initrd.target") + test_client() + client.switch_root() + + client.wait_for_unit("multi-user.target") + test_client() ''; })