Merge pull request #304322 from ElvishJerricco/sd-s1-resolved

nixos/systemd-stage-1: Support resolved
This commit is contained in:
Florian Klink
2024-05-23 10:46:51 +03:00
committed by GitHub
4 changed files with 174 additions and 53 deletions
+6 -2
View File
@@ -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" ];
};
})
+92 -51
View File
@@ -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,60 +140,87 @@ 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}
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'
'';
# 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 = [ "sysinit.target" ];
aliases = [ "dbus-org.freedesktop.resolve1.service" ];
restartTriggers = [ config.environment.etc."systemd/resolved.conf".source ];
};
environment.etc = {
"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
"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;
})
(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" ];
};
};
})
];
}
+1
View File
@@ -930,6 +930,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;
+75
View File
@@ -0,0 +1,75 @@
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;
testing.initrdBackdoor = true;
boot.initrd = {
systemd.enable = true;
systemd.initrdBin = [ pkgs.iputils ];
network.enable = true;
services.resolved.enable = true;
};
};
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")
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()
'';
})