Merge pull request #123598 from pschyska/master

nixos/nsd: make nsd-checkconf work when configuration contains keys (#118140)

Changed files
+28 -3
nixos
modules
services
networking
tests
+19 -3
nixos/modules/services/networking/nsd.nix
···
mkZoneFileName = name: if name == "." then "root" else name;
nsdEnv = pkgs.buildEnv {
name = "nsd-env";
···
echo "|- checking zone '$out/zones/$zoneFile'"
${nsdPkg}/sbin/nsd-checkzone "$zoneFile" "$zoneFile" || {
if grep -q \\\\\\$ "$zoneFile"; then
-
echo zone "$zoneFile" contains escaped dollar signes \\\$
-
echo Escaping them is not needed any more. Please make shure \
-
to unescape them where they prefix a variable name
fi
exit 1
···
done
echo "checking configuration file"
${nsdPkg}/sbin/nsd-checkconf $out/nsd.conf
'';
};
···
mkZoneFileName = name: if name == "." then "root" else name;
+
# replaces include: directives for keys with fake keys for nsd-checkconf
+
injectFakeKeys = keys: concatStrings
+
(mapAttrsToList
+
(keyName: keyOptions: ''
+
fakeKey="$(${pkgs.bind}/bin/tsig-keygen -a ${escapeShellArgs [ keyOptions.algorithm keyName ]} | grep -oP "\s*secret \"\K.*(?=\";)")"
+
sed "s@^\s*include:\s*\"${stateDir}/private/${keyName}\"\$@secret: $fakeKey@" -i $out/nsd.conf
+
'')
+
keys);
+
nsdEnv = pkgs.buildEnv {
name = "nsd-env";
···
echo "|- checking zone '$out/zones/$zoneFile'"
${nsdPkg}/sbin/nsd-checkzone "$zoneFile" "$zoneFile" || {
if grep -q \\\\\\$ "$zoneFile"; then
+
echo zone "$zoneFile" contains escaped dollar signs \\\$
+
echo Escaping them is not needed any more. Please make sure \
+
to unescape them where they prefix a variable name.
fi
exit 1
···
done
echo "checking configuration file"
+
# Save original config file including key references...
+
cp $out/nsd.conf{,.orig}
+
# ...inject mock keys into config
+
${injectFakeKeys cfg.keys}
+
# ...do the checkconf
${nsdPkg}/sbin/nsd-checkconf $out/nsd.conf
+
# ... and restore original config file.
+
mv $out/nsd.conf{.orig,}
'';
};
+9
nixos/tests/nsd.nix
···
services.nsd.enable = true;
services.nsd.rootServer = true;
services.nsd.interfaces = lib.mkForce [];
services.nsd.zones."example.com.".data = ''
@ SOA ns.example.com noc.example.com 666 7200 3600 1209600 3600
ipv4 A 1.2.3.4
···
ns A 192.168.0.1
ns AAAA dead:beef::1
'';
services.nsd.zones."deleg.example.com.".data = ''
@ SOA ns.example.com noc.example.com 666 7200 3600 1209600 3600
@ A 9.8.7.6
···
clientv6.wait_for_unit("network.target")
server.wait_for_unit("nsd.service")
def assert_host(type, rr, query, expected):
self = clientv4 if type == 4 else clientv6
···
services.nsd.enable = true;
services.nsd.rootServer = true;
services.nsd.interfaces = lib.mkForce [];
+
services.nsd.keys."tsig.example.com." = {
+
algorithm = "hmac-sha256";
+
keyFile = pkgs.writeTextFile { name = "tsig.example.com."; text = "aR3FJA92+bxRSyosadsJ8Aeeav5TngQW/H/EF9veXbc="; };
+
};
services.nsd.zones."example.com.".data = ''
@ SOA ns.example.com noc.example.com 666 7200 3600 1209600 3600
ipv4 A 1.2.3.4
···
ns A 192.168.0.1
ns AAAA dead:beef::1
'';
+
services.nsd.zones."example.com.".provideXFR = [ "0.0.0.0 tsig.example.com." ];
services.nsd.zones."deleg.example.com.".data = ''
@ SOA ns.example.com noc.example.com 666 7200 3600 1209600 3600
@ A 9.8.7.6
···
clientv6.wait_for_unit("network.target")
server.wait_for_unit("nsd.service")
+
with subtest("server tsig.example.com."):
+
expected_tsig = " secret: \"aR3FJA92+bxRSyosadsJ8Aeeav5TngQW/H/EF9veXbc=\"\n"
+
tsig=server.succeed("cat /var/lib/nsd/private/tsig.example.com.")
+
assert expected_tsig == tsig, f"Expected /var/lib/nsd/private/tsig.example.com. to contain '{expected_tsig}', but found '{tsig}'"
def assert_host(type, rr, query, expected):
self = clientv4 if type == 4 else clientv6