Merge pull request #304322 from ElvishJerricco/sd-s1-resolved
nixos/systemd-stage-1: Support resolved
This commit is contained in:
@@ -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" ];
|
||||
};
|
||||
})
|
||||
|
||||
@@ -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" ];
|
||||
};
|
||||
};
|
||||
|
||||
})
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
'';
|
||||
})
|
||||
Reference in New Issue
Block a user