IP address hints in HTTPS DNS records

In this thread from 2022, SVCB and HTTPS queries were discussed. Since then, HTTPS RR types have become more widespread through support by Apple, Cloudflare, and others.

These records can contain hints for IPv4 and IPv6 addresses which can be used by the client to skip A and AAAA lookups. For example:

❯ dig +short HTTPS discord.com @192.168.1.2

1 . alpn="h3,h2" ipv4hint=162.159.128.233,162.159.135.232,162.159.136.232,162.159.137.232,162.159.138.232

Should Pi-hole process these resource records and modify the hints (e.g. to return 0.0.0.0 or a local IP, depending on blocking mode) or remove the hints so that clients are forced to fall back to A and AAAA records?

You can already use pihole to block these queries. I'm using a regex blacklist:

In addition, I use suricata rules to ensure HTTPS and SVCB queries don't even reach pihole:

reject dns <IPv4 source range> any -> any 53 (msg:"SVCB query"; content:"|00 01 00 00 00 00 00|"; content:"|00 00 40 00 01|"; fast_pattern; distance:5; classtype:external-ip-check; sid:1000005; rev:5; metadata:affected_product Any, attack_target Client_Endpoint, created_at 2023_01_01, deployment Perimeter, signature_severity Minor, updated_at 2023_05_28;)
reject dns <IPv4 source range> any -> any 53 (msg:"HTTPS query"; content:"|00 01 00 00 00 00 00|"; content:"|00 00 41 00 01|"; fast_pattern; distance:5; classtype:external-ip-check; sid:1000006; rev:5; metadata:affected_product Any, attack_target Client_Endpoint, created_at 2023_01_01, deployment Perimeter, signature_severity Minor, updated_at 2023_05_28;)
reject dns <IPv6 source range> any -> any 53 (msg:"SVCB query"; content:"|00 01 00 00 00 00 00|"; content:"|00 00 40 00 01|"; fast_pattern; distance:5; classtype:external-ip-check; sid:1000007; rev:5; metadata:affected_product Any, attack_target Client_Endpoint, created_at 2023_01_01, deployment Perimeter, signature_severity Minor, updated_at 2023_05_28;)
reject dns <IPv6 source range> any -> any 53 (msg:"HTTPS query"; content:"|00 01 00 00 00 00 00|"; content:"|00 00 41 00 01|"; fast_pattern; distance:5; classtype:external-ip-check; sid:1000008; rev:5; metadata:affected_product Any, attack_target Client_Endpoint, created_at 2023_01_01, deployment Perimeter, signature_severity Minor, updated_at 2023_05_28;)

As a result the dashboard usually only shows these query types:

Yes, blocking these queries wholesale is possible, but you lose some of the benefits when doing so. It means that the client has to fall back to the slow protocol negotiation (e.g. HTTP -> HTTPS -> HTTP/2) as described in Speeding up HTTPS and HTTP/3 negotiation with... DNS. By removing these queries, you increase latency for all non-blocked domains and trade that for a better filtering of blocked ones.

Pi-hole's filtering is operating on inspection of DNS requests.

Your question would imply that Pi-hole would have to inspect DNS replies, which it currently does not do, and which would come at potentially severe penalties.

But why would you want to block those records that you mention to begin with?

Note that those ipv4hints contain the exact same IPv4 addresses as an A request would return:

$ dig -t A +short discord.com
162.159.135.232
162.159.138.232
162.159.128.233
162.159.136.232
162.159.137.232

Even if they would be different, RFC9460 would prefer original A/AAAA records over ip*hints:

If A and AAAA records for TargetName are locally available, the client SHOULD ignore these hints.

It's true that those SVCB/HTTPS records could indicate that a DoT or DoQ server is operational for a given domain, which in turn may prompt a client to use those to by-pass local DNS resolution.

In the majority of cases, however, HTTPS records are actually beneficial, as they may speed up application layer protocol negotiation.

Without HTTPS, a browser would e.g. issue the following requests:
a. to DNS server: request for A record, reply is IPv4 address
b. to DNS server: request for AAAA record, reply is IPv6 address
c. to web Server at IP address: plain text HTTP request, reply is redirection to use TLS via HTTP/2
d. to web Server at IP address: TLS HTTP/2 request, reply is redirection to use HTTP/3
e. to web Server at IP address: TLS HTTP/3 request, reply is website contents

In the presence of an HTTPS record, this would become:
a. to DNS server: request for HTTPS record, reply is alpn protocol (HTTP/3), ipv4hints (IPv4 address), ipv6hints (IPv6 address), port (Alternate, non-standard port to use)
b. to web Server at IP address: TLS HTTP/3 request, reply is website contents

An older survey (November 2023) suggested that then around 25% of the top 1 million domains were offering HTTPS records, and just under 5% of ~270 million total tested domains (see netmeister's Use of HTTPS Resource Records).

For both sets, h3 and h2 alpn protocols have been the vast majority of parameters observed in use, with only 11 samples within the Top1M and 125 samples within the ~270M domains referring to different protocols.

This would imply that blocking HTTPS records in general, while keeping clients from potentially switching to an alternate DNS server for a specific domain, it would preclude you from the benefits of faster website loading for all domains that support alpn with their HTTPS DNS records (which the survey stated to be ~99% of all sites supporting HTTPS).

Yeah, I agree that blocking HTTPS not the right solution. The lower latency for the protocol negotiation is nice.

Let me explain my use case a bit more: I'm running a split-view DNS where some domains resolve to internal IPs inside the LAN but to external IPs when using a public DNS. I noticed that Safari (not Chrome) was still using the external IPs and traced this down to the HTTPS resource records. So even in the presence of A records, the IPv4 hints took precedence (maybe contrary to the RFC).

Your point about processing replies is a good one. Maybe Pi-hole just isn't the right tool for this. I've now set up Unbound as upstream and added local data for those addresses. It's redundant to the A records (which are in a different system), but that seems to get the job done:

local-data: 'my.local.domain. HTTPS 1 . alpn="h2" ipv4hint=local_ip'

I see. :wink:

That's a more specific problem than your original question, and in that specific case, configuring Pi-hole to block HTTPS records exclusively for that specific domain of yours should also have worked, e.g.:

mydomain.com;querytype=HTTPS;reply=NODATA

Yes, except that I don't want it to apply to all records in that domain and instead of dropping, I'd like to keep the "alpn" hint because these services actually do serve HTTP/2 (and for the same reason, replying with a IP hint would retain the latency benefits as well).

But it's a good-enough solution for when there is no Unbound. Thanks!

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.