blob: cc4ca5260dfa9416ef39c75e4dba557dfea9e62c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
# This test verifies that systemd-timesyncd can resolve the NTP server hostname when DNSSEC validation
# fails even though it is enforced in the systemd-resolved settings. It is required in order to solve
# the chicken-and-egg problem when DNSSEC validation needs the correct time to work, but to set the
# correct time, we need to connect to an NTP server, which usually requires resolving its hostname.
#
# This test does the following:
# - Sets up a DNS server (tinydns) listening on loopback, serving .ntp and fake.ntp records.
# - Configures that DNS server as a resolver and enables DNSSEC in systemd-resolved settings.
# - Configures systemd-timesyncd to use fake.ntp hostname as an NTP server.
# - Performs a regular DNS lookup, to ensure it fails due to broken DNSSEC.
# - Waits until systemd-timesyncd resolves fake.ntp by checking its debug output.
# Here, we don't expect systemd-timesyncd to connect and synchronize time because there is no NTP
# server running. For this test to succeed, we only need to ensure that systemd-timesyncd
# resolves the IP address of the fake.ntp host.
let
ntpHostname = "fake.ntp";
ntpIP = "192.0.2.1";
dnsIP = "127.0.0.1";
in
{
name = "systemd-timesyncd-nscd-dnssec";
nodes.machine =
{ lib, ... }:
{
# Setup a local DNS server for the NTP domain on loopback
services.tinydns = {
enable = true;
ip = dnsIP;
data = ''
.ntp:${dnsIP}
+.${ntpHostname}:${ntpIP}
'';
};
# Enable systemd-resolved with DNSSEC and use the local DNS as a name server
services.resolved.enable = true;
services.resolved.settings.Resolve.DNSSEC = true;
networking.nameservers = [ dnsIP ];
# Configure systemd-timesyncd to use our NTP hostname
services.timesyncd.enable = lib.mkForce true;
services.timesyncd.servers = [ ntpHostname ];
services.timesyncd.settings.Time.FallbackNTP = ntpHostname;
# The debug output is necessary to determine whether systemd-timesyncd successfully resolves our NTP hostname or not
systemd.services.systemd-timesyncd.environment.SYSTEMD_LOG_LEVEL = "debug";
};
testScript = ''
machine.wait_for_unit("tinydns.service")
machine.wait_for_unit("systemd-timesyncd.service")
machine.fail("resolvectl query ${ntpHostname}")
machine.wait_until_succeeds("journalctl -u systemd-timesyncd.service --grep='Resolved address ${ntpIP}:123 for ${ntpHostname}'")
'';
}
|