mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-12-24 14:43:37 +00:00
6008246790
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.
62 lines
2.6 KiB
Nix
62 lines
2.6 KiB
Nix
# 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}'")
|
|
'';
|
|
})
|