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