Bug 2212111

Summary: [RFE] Design and implement a way to auto-correct time with DNSSEC validation enabled early on boot
Product: [Fedora] Fedora Reporter: Petr Menšík <pemensik>
Component: unboundAssignee: Paul Wouters <paul.wouters>
Status: NEW --- QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: low Docs Contact:
Priority: unspecified    
Version: rawhideCC: akhaitovich, paul.wouters, pemensik, pj.pandit
Target Milestone: ---Keywords: FutureFeature, RFE
Target Release: ---   
Hardware: Unspecified   
OS: Linux   
URL: https://lists.nlnetlabs.nl/pipermail/unbound-users/2023-April/008075.html
Whiteboard:
Fixed In Version: Doc Type: Enhancement
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Petr Menšík 2023-06-03 22:55:12 UTC
Link to unbound thread:
https://lists.nlnetlabs.nl/pipermail/unbound-users/2023-April/008075.html

I would like to have Fedora ready to enable DNSSEC eventually in default installation. But I stumbled on issue with systemd-resolved, where it prevented resolution of default fedora ntp server specified by the distribution. In unbound the problem would be similar.

Problem is that ntp service chrony does not use special DNS library, so it does not know times used in DNSSEC signatures. And unbound (or any other validating resolver) does not know secure obtained

Reproducible: Didn't try

Steps to Reproduce:
1. Have incorrect time or unknown time for the machine
2. Have dnssec validation resolver started early during boot.
3. Expect NTP service will correct time, without lowering significantly security of the system
Actual Results:  
ntp.org is not DNSSEC signed, but org. zone is. If the time is wrong, validating resolver will return SERVFAIL. That makes chrony fail to 

Expected Results:  
If the name can be resolved, the system should have mechanism to auto-correct system time without disabling DNSSEC protection as best as it can.

Mirek Lichvar proposed to use fixed IP addresses to overcome such issues. That is certainly possible and should be preferred, if NTP servers are obtained from network. But if the network does not specify IP addresses, we have a name which should be resolved. Fixed address in /etc/hosts should not be used, because that would never be updated automatically. Chrony saving last working addresses on shutdown might be a way.

One possibility is to have cached IP addresses from last successful resolution. If the resolution fails, try to obtain time from address, which worked before. Installation media might contain initial hints saved during image build.

Daisuke HIGASHI provided hint: Unbound supports val-override-date: -1 mode, where it will check only signatures, but not timestamp ranges. That is certainly better than disabling DNSSEC validation until we have trusted time.

As pointed Tony Finch, we should prevent replay attack and use some lower bound. So instead of not checking timestamps at all, we should specify lowest verified time. Chrony saves drifts and that should have last known time saved. On installation media we might use the most recent modification timestamp as lower bound. Timestamps expired before that date should be ignored.

- Chrony should have a way to provide us trustworthy lower bound.
- Unbound should have a way to indicate it is the system time, which prevents (some) successful resolutions.
- Chrony might be able to trigger special mode, where val-override-date: -1 would be enabled. But should do that only in case the time is the issue. It should not enable it if network connectivity is the real cause. Any attacker should not be able to trigger this mode to take advantage of lowered security.

Comment 1 Petr Menšík 2023-06-03 23:04:14 UTC
I think statistics counter increasing each time the timestamp were not accepted for RRSIG, but otherwise the signature would pass, would be helpful. That would allow chrony to trigger time synchronization event, where we try to accept wider range of time for a initial time set. It could query that counter if all names known failed to resolve, whether to enable the special mode. But if it worked fine, it would boot with full security.

Useful for devices without RTC like raspberry PI or old devices, where the clock got wrong for whatever reason.

Comment 2 Petr Menšík 2023-06-05 15:06:20 UTC
Found interesting requirement:
https://www.ietf.org/archive/id/draft-ietf-dnsop-dnssec-validator-requirements-04.html#name-time-deviation-and-absence-

STARTUP:
A DRO MUST provide a mean to update the time without relying on DNSSEC when the DNSSEC validator is started. The resolver MUST NOT start if the time synchronization does not succeed at start time.

...
 In other words, the mechanisms may have to update the time over an unsecure DNSSEC resolution.

^ The problem I see with this is getaddrinfo() in glibc does not provide a way to make unsecure resolution. It either works or not. Usage of dns-specific API like res_query() would not use /etc/hosts and similar databases. So they can result in different responses.

It seems to me we should add ability to request validation of timestamps disabled in a query. Which is possible with CD bit set in DNS query, but nothing such is available in getaddrinfo().