diff options
author | Yuri Nesterov <yuriy.nesterov@unikie.com> | 2023-06-22 15:17:42 +0300 |
---|---|---|
committer | Yuri Nesterov <yuriy.nesterov@unikie.com> | 2023-12-20 13:21:43 +0200 |
commit | 6008246790d4b3eb27c02d3a9b9424b91f55a8b4 (patch) | |
tree | e247a39b0743f36bc5fdf919e21551f68a91661b /nixos/tests/systemd-timesyncd-nscd-dnssec.nix | |
parent | 688991ba84af0bf9518e5f0a3c2c471474a358e0 (diff) |
systemd: disable NSCD when DNSSEC validation is disabled in timesyncd
When a system has a wrong date and time timesyncd is unable to synchronize it because DNSSEC doesn't work. In order to break this chicken and egg problem systemd-timesync disables DNSSEC validation by setting SYSTEMD_NSS_RESOLVE_VALIDATE=0 in the unit file. However, it doesn't work in NixOS because it uses NSCD. This patch disables NSCD in systemd-timesyncd when SYSTEMD_NSS_RESOLVE_VALIDATE is set to 0 so that it uses NSS libraries directly. In order for it to be able to find the libnss_resolve.so.2 library this patch adds the systemd directory in the nix store to the LD_LIBRARY_PATH.
Diffstat (limited to 'nixos/tests/systemd-timesyncd-nscd-dnssec.nix')
-rw-r--r-- | nixos/tests/systemd-timesyncd-nscd-dnssec.nix | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/nixos/tests/systemd-timesyncd-nscd-dnssec.nix b/nixos/tests/systemd-timesyncd-nscd-dnssec.nix new file mode 100644 index 0000000000000..697dd824e3453 --- /dev/null +++ b/nixos/tests/systemd-timesyncd-nscd-dnssec.nix @@ -0,0 +1,61 @@ +# 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 the eth1 ip addess, 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. + +import ./make-test-python.nix ({ pkgs, ... }: + +let + ntpHostname = "fake.ntp"; + ntpIP = "192.0.2.1"; +in +{ + name = "systemd-timesyncd"; + nodes.machine = { pkgs, lib, config, ... }: + let + eth1IP = (lib.head config.networking.interfaces.eth1.ipv4.addresses).address; + in + { + # Setup a local DNS server for the NTP domain on the eth1 IP address + services.tinydns = { + enable = true; + ip = eth1IP; + data = '' + .ntp:${eth1IP} + +.${ntpHostname}:${ntpIP} + ''; + }; + + # Enable systemd-resolved with DNSSEC and use the local DNS as a name server + services.resolved.enable = true; + services.resolved.dnssec = "true"; + networking.nameservers = [ eth1IP ]; + + # Configure systemd-timesyncd to use our NTP hostname + services.timesyncd.enable = lib.mkForce true; + services.timesyncd.servers = [ ntpHostname ]; + services.timesyncd.extraConfig = '' + 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}'") + ''; +}) |