From 8b62f630658ccc370cf96321cc81e08b4b77647f Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 24 Oct 2024 10:28:20 +1100 Subject: [PATCH] chore(connlib): respond with empty records to HTTPS query (#7141) Applications may query domains for HTTPS RR using the HTTPS record type. `connlib` operates on OSI layer 3 and thus can only hand out IPs for the particular domains. The correct way to signal this to applications is to answer the HTTPS query with NOERROR and return an empty set of records. [RFC9460](https://www.rfc-editor.org/rfc/rfc9460.html#name-client-behavior) says the following: > 4. If one or more "compatible" ([Section 8](https://www.rfc-editor.org/rfc/rfc9460.html#mandatory)) ServiceMode records are returned, these represent the alternative endpoints. Sort the records by ascending SvcPriority. > 5. Otherwise, SVCB resolution has failed, and the list of available endpoints is empty. This implies that returning no records is valid behaviour and forces the client to consider the HTTPS DNS query as failed and query for A / AAAA records instead (if it didn't do so via happy-eyeballs already). --- rust/connlib/tunnel/src/dns.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/rust/connlib/tunnel/src/dns.rs b/rust/connlib/tunnel/src/dns.rs index 68fab3926..a447b18c6 100644 --- a/rust/connlib/tunnel/src/dns.rs +++ b/rust/connlib/tunnel/src/dns.rs @@ -333,9 +333,11 @@ impl StubResolver { vec![AllRecordData::Ptr(domain::rdata::Ptr::new(fqdn))] } (Rtype::HTTPS, Some(_)) => { - anyhow::bail!( - "Discarding HTTPS record query for resource {domain} because we can't mangle it" - ); + // We must intercept queries for the HTTPS record type to force the client to issue an A / AAAA query instead. + // Otherwise, the client won't use the IPs we issue for a particular domain and the traffic cannot be tunneled. + + let response = build_dns_with_answer(message, domain, Vec::default())?; + return Ok(ResolveStrategy::LocalResponse(response)); } _ => return Ok(ResolveStrategy::Recurse), };