Skip to content

Commit

Permalink
Merge pull request #304322 from ElvishJerricco/sd-s1-resolved
Browse files Browse the repository at this point in the history
nixos/systemd-stage-1: Support resolved
  • Loading branch information
flokli committed May 23, 2024
2 parents 8da1a55 + bfdba4d commit fadd3fe
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 53 deletions.
8 changes: 6 additions & 2 deletions nixos/modules/services/system/dbus.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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" ];
};
})
Expand Down
143 changes: 92 additions & 51 deletions nixos/modules/system/boot/resolved.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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
{

Expand Down Expand Up @@ -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 change: 1 addition & 0 deletions nixos/tests/all-tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
75 changes: 75 additions & 0 deletions nixos/tests/systemd-resolved.nix
Original file line number Diff line number Diff line change
@@ -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()
'';
})

0 comments on commit fadd3fe

Please sign in to comment.