mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-06-05 21:03:40 +00:00
nixos/systemd-resolved: add support to generate dns-delegate files
See https://www.freedesktop.org/software/systemd/man/258/systemd.dns-delegate.html
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
utils,
|
||||
...
|
||||
}:
|
||||
@@ -14,12 +13,15 @@ let
|
||||
elem
|
||||
isList
|
||||
literalExpression
|
||||
mapAttrs'
|
||||
mapAttrsToList
|
||||
mkIf
|
||||
mkMerge
|
||||
mkOption
|
||||
mkOrder
|
||||
mkRenamedOptionModule
|
||||
mkRemovedOptionModule
|
||||
nameValuePair
|
||||
optionalAttrs
|
||||
types
|
||||
;
|
||||
@@ -132,6 +134,27 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
dnsDelegates = mkOption {
|
||||
description = ''
|
||||
dns-delegate files to be created.
|
||||
See {manpage}`systemd.dns-delegate(5)` for more info.
|
||||
'';
|
||||
default = { };
|
||||
type = types.attrsOf (
|
||||
types.submodule {
|
||||
options.Delegate = mkOption {
|
||||
description = ''
|
||||
Settings option for systemd dns-delegate files.
|
||||
See {manpage}`systemd.dns-delegate(5)` for all available options.
|
||||
'';
|
||||
type = types.submodule {
|
||||
freeformType = types.attrsOf unitOption;
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
boot.initrd.services.resolved.enable = mkOption {
|
||||
@@ -167,7 +190,12 @@ in
|
||||
systemd.services.systemd-resolved = {
|
||||
wantedBy = [ "sysinit.target" ];
|
||||
aliases = [ "dbus-org.freedesktop.resolve1.service" ];
|
||||
reloadTriggers = [ config.environment.etc."systemd/resolved.conf".source ];
|
||||
reloadTriggers = [
|
||||
config.environment.etc."systemd/resolved.conf".source
|
||||
]
|
||||
++ mapAttrsToList (
|
||||
name: _: config.environment.etc."systemd/dns-delegate.d/${name}.dns-delegate".source
|
||||
) cfg.dnsDelegates;
|
||||
stopIfChanged = false;
|
||||
};
|
||||
|
||||
@@ -180,7 +208,13 @@ in
|
||||
}
|
||||
// optionalAttrs dnsmasqResolve {
|
||||
"dnsmasq-resolv.conf".source = "/run/systemd/resolve/resolv.conf";
|
||||
};
|
||||
}
|
||||
// mapAttrs' (
|
||||
name: value:
|
||||
nameValuePair "systemd/dns-delegate.d/${name}.dns-delegate" {
|
||||
text = settingsToSections (transformSettings value);
|
||||
}
|
||||
) cfg.dnsDelegates;
|
||||
|
||||
# If networkmanager is enabled, ask it to interface with resolved.
|
||||
networking.networkmanager.dns = "systemd-resolved";
|
||||
|
||||
@@ -36,13 +36,48 @@
|
||||
};
|
||||
};
|
||||
|
||||
nodes.delegate_server =
|
||||
{ lib, config, ... }:
|
||||
let
|
||||
delegateZone = pkgs.writeTextDir "delegated.example.org.zone" ''
|
||||
@ SOA ns.delegated.example.org. noc.delegated.example.org. 2019031301 86400 7200 3600000 172800
|
||||
test A ${(lib.head config.networking.interfaces.eth1.ipv4.addresses).address}
|
||||
test 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::3";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
|
||||
services.knot = {
|
||||
enable = true;
|
||||
settings = {
|
||||
server.listen = [
|
||||
"0.0.0.0@53"
|
||||
"::@53"
|
||||
];
|
||||
template.default.storage = delegateZone;
|
||||
zone."delegated.example.org".file = "delegated.example.org.zone";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
nodes.client =
|
||||
{ nodes, ... }:
|
||||
let
|
||||
inherit (lib.head nodes.server.networking.interfaces.eth1.ipv4.addresses) address;
|
||||
serverAddress = (lib.head nodes.server.networking.interfaces.eth1.ipv4.addresses).address;
|
||||
delegateAddress =
|
||||
(lib.head nodes.delegate_server.networking.interfaces.eth1.ipv4.addresses).address;
|
||||
in
|
||||
{
|
||||
networking.nameservers = [ address ];
|
||||
networking.nameservers = [ serverAddress ];
|
||||
networking.interfaces.eth1.ipv6.addresses = lib.mkForce [
|
||||
{
|
||||
address = "fd00::2";
|
||||
@@ -51,6 +86,12 @@
|
||||
];
|
||||
services.resolved.enable = true;
|
||||
services.resolved.settings.Resolve.FallbackDNS = [ ];
|
||||
services.resolved.dnsDelegates.example-org = {
|
||||
Delegate = {
|
||||
DNS = delegateAddress;
|
||||
Domains = [ "delegated.example.org" ];
|
||||
};
|
||||
};
|
||||
networking.useNetworkd = true;
|
||||
networking.useDHCP = false;
|
||||
systemd.network.networks."40-eth0".enable = false;
|
||||
@@ -69,23 +110,35 @@
|
||||
let
|
||||
address4 = (lib.head nodes.server.networking.interfaces.eth1.ipv4.addresses).address;
|
||||
address6 = (lib.head nodes.server.networking.interfaces.eth1.ipv6.addresses).address;
|
||||
delegateAddress4 =
|
||||
(lib.head nodes.delegate_server.networking.interfaces.eth1.ipv4.addresses).address;
|
||||
delegateAddress6 =
|
||||
(lib.head nodes.delegate_server.networking.interfaces.eth1.ipv6.addresses).address;
|
||||
in
|
||||
#python
|
||||
''
|
||||
start_all()
|
||||
server.wait_for_unit("multi-user.target")
|
||||
delegate_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")
|
||||
def test_resolve(domain, expected_addrs):
|
||||
query = client.succeed(f"resolvectl query {domain}")
|
||||
for addr in expected_addrs:
|
||||
assert addr in query, f"Expected {addr} in: {query}"
|
||||
client.succeed(f"ping -4 -c 1 {domain}")
|
||||
client.succeed(f"ping -6 -c 1 {domain}")
|
||||
|
||||
with subtest("resolve in initrd"):
|
||||
client.wait_for_unit("initrd.target")
|
||||
test_resolve("example.com", ["${address4}", "${address6}"])
|
||||
|
||||
client.wait_for_unit("initrd.target")
|
||||
test_client()
|
||||
client.switch_root()
|
||||
|
||||
client.wait_for_unit("multi-user.target")
|
||||
test_client()
|
||||
with subtest("resolve after switch-root"):
|
||||
client.wait_for_unit("multi-user.target")
|
||||
test_resolve("example.com", ["${address4}", "${address6}"])
|
||||
|
||||
with subtest("dns-delegate resolves delegated subdomain"):
|
||||
test_resolve("test.delegated.example.org", ["${delegateAddress4}", "${delegateAddress6}"])
|
||||
'';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user