at 25.11-pre 2.8 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 addess, 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 16import ./make-test-python.nix ( 17 { pkgs, ... }: 18 19 let 20 ntpHostname = "fake.ntp"; 21 ntpIP = "192.0.2.1"; 22 in 23 { 24 name = "systemd-timesyncd"; 25 nodes.machine = 26 { 27 pkgs, 28 lib, 29 config, 30 ... 31 }: 32 let 33 eth1IP = (lib.head config.networking.interfaces.eth1.ipv4.addresses).address; 34 in 35 { 36 # Setup a local DNS server for the NTP domain on the eth1 IP address 37 services.tinydns = { 38 enable = true; 39 ip = eth1IP; 40 data = '' 41 .ntp:${eth1IP} 42 +.${ntpHostname}:${ntpIP} 43 ''; 44 }; 45 46 # Enable systemd-resolved with DNSSEC and use the local DNS as a name server 47 services.resolved.enable = true; 48 services.resolved.dnssec = "true"; 49 networking.nameservers = [ eth1IP ]; 50 51 # Configure systemd-timesyncd to use our NTP hostname 52 services.timesyncd.enable = lib.mkForce true; 53 services.timesyncd.servers = [ ntpHostname ]; 54 services.timesyncd.extraConfig = '' 55 FallbackNTP=${ntpHostname} 56 ''; 57 58 # The debug output is necessary to determine whether systemd-timesyncd successfully resolves our NTP hostname or not 59 systemd.services.systemd-timesyncd.environment.SYSTEMD_LOG_LEVEL = "debug"; 60 }; 61 62 testScript = '' 63 machine.wait_for_unit("tinydns.service") 64 machine.wait_for_unit("systemd-timesyncd.service") 65 machine.fail("resolvectl query ${ntpHostname}") 66 machine.wait_until_succeeds("journalctl -u systemd-timesyncd.service --grep='Resolved address ${ntpIP}:123 for ${ntpHostname}'") 67 ''; 68 } 69)