Skip to content

Commit 2a8e59e

Browse files
authored
Fix/block cloudflare ech type65
* fix(dns): block Cloudflare TYPE65/HTTPS records to prevent ECH failures Chrome and Safari query Cloudflare-published HTTPS (TYPE65) records for proxied domains, which include ECH parameters tied to Cloudflare's edge. When PiHole resolves these domains to local Caddy IPs instead of Cloudflare, browsers attempt ECH against a server that doesn't support it, causing ERR_SSL_PROTOCOL_ERROR. Firefox handles ECH retry gracefully; Chrome and Safari fail hard. Fix: add local-zone 'static' blocks in Unbound for geeksbsmrt.com and smrtgeekdevs.com. Unbound returns SERVFAIL for TYPE65 since no local-data is defined for that type, while PiHole's address= directives continue to serve A records for all subdomains. Also adds Access-Control-Allow-Private-Network header to Caddy's external snippet as a defensive measure for Chrome LNA (Private Network Access) restrictions. Affected: docker/unbound/unbound.conf (new), docker/caddy/Caddyfile * fix(dns): remove hardcoded IPs from unbound local-zone config local-data A record entries were redundant -- PiHole handles all A record lookups for these zones via its own address= directives and never forwards them to Unbound. Only TYPE65 (HTTPS/ECH) queries reach Unbound for these domains, so local-zone: static alone is sufficient to return NXDOMAIN. Removing local-data eliminates the hardcoded internal IP scheme from the repo while preserving the fix.
1 parent 595a26c commit 2a8e59e

2 files changed

Lines changed: 89 additions & 0 deletions

File tree

docker/caddy/Caddyfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ uptime.home {
7474
Referrer-Policy "strict-origin-when-cross-origin"
7575
Cache-Control "public, max-age=15, must-revalidate"
7676
Permissions-Policy "accelerometer=(), ambient-light-sensor=(), autoplay=(self), camera=(), encrypted-media=(), fullscreen=(self), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(*), speaker-selection=(), usb=(), xr-spatial-tracking=()"
77+
Access-Control-Allow-Private-Network "true"
7778
[defer]
7879
}
7980
file_server

docker/unbound/unbound.conf

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
server:
2+
# If no logfile is specified, syslog is used
3+
# logfile: "/var/log/unbound/unbound.log"
4+
verbosity: 0
5+
6+
interface-automatic: yes
7+
do-ip4: yes
8+
do-udp: yes
9+
do-tcp: yes
10+
11+
# May be set to no if you don't have IPv6 connectivity
12+
do-ip6: yes
13+
14+
# You want to leave this to no unless you have *native* IPv6. With 6to4 and
15+
# Terredo tunnels your web browser should favor IPv4 for the same reasons
16+
prefer-ip6: no
17+
18+
# Use this only when you downloaded the list of primary root servers!
19+
# If you use the default dns-root-data package, unbound will find it automatically
20+
#root-hints: "/var/lib/unbound/root.hints"
21+
22+
# Trust glue only if it is within the server's authority
23+
harden-glue: yes
24+
25+
# Require DNSSEC data for trust-anchored zones, if such data is absent, the zone becomes BOGUS
26+
harden-dnssec-stripped: yes
27+
28+
# Don't use Capitalization randomization as it known to cause DNSSEC issues sometimes
29+
# see https://discourse.pi-hole.net/t/unbound-stubby-or-dnscrypt-proxy/9378 for further details
30+
use-caps-for-id: no
31+
32+
# Reduce EDNS reassembly buffer size.
33+
# IP fragmentation is unreliable on the Internet today, and can cause
34+
# transmission failures when large DNS messages are sent via UDP. Even
35+
# when fragmentation does work, it may not be secure; it is theoretically
36+
# possible to spoof parts of a fragmented DNS message, without easy
37+
# detection at the receiving end. Recently, there was an excellent study
38+
# >>> Defragmenting DNS - Determining the optimal maximum UDP response size for DNS <<<
39+
# by Axel Koolhaas, and Tjeerd Slokker (https://indico.dns-oarc.net/event/36/contributions/776/)
40+
# in collaboration with NLnet Labs explored DNS using real world data from the
41+
# the RIPE Atlas probes and the researchers suggested different values for
42+
# IPv4 and IPv6 and in different scenarios. They advise that servers should
43+
# be configured to limit DNS messages sent over UDP to a size that will not
44+
# trigger fragmentation on typical network links. DNS servers can switch
45+
# from UDP to TCP when a DNS response is too big to fit in this limited
46+
# buffer size. This value has also been suggested in DNS Flag Day 2020.
47+
edns-buffer-size: 1232
48+
49+
# Perform prefetching of close to expired message cache entries
50+
# This only applies to domains that have been frequently queried
51+
prefetch: yes
52+
53+
# One thread should be sufficient, can be increased on beefy machines. In reality for most users running on small networks or on a single machine, it should be unnecessary to seek performance enhancement by increasing num-threads above 1.
54+
num-threads: 1
55+
56+
# Ensure kernel buffer is large enough to not lose messages in traffic spikes
57+
so-rcvbuf: 1m
58+
59+
# Ensure privacy of local IP ranges
60+
private-address: 192.168.0.0/16
61+
private-address: 169.254.0.0/16
62+
private-address: 172.16.0.0/12
63+
private-address: 10.0.0.0/8
64+
private-address: fd00::/8
65+
private-address: fe80::/10
66+
67+
# Ensure no reverse queries to non-public IP ranges (RFC6303 4.2)
68+
private-address: 192.0.2.0/24
69+
private-address: 198.51.100.0/24
70+
private-address: 203.0.113.0/24
71+
private-address: 255.255.255.255/32
72+
private-address: 2001:db8::/32
73+
74+
access-control: 192.168.254.1/32 allow
75+
access-control: 192.168.254.223/32 allow
76+
access-control: 0.0.0.0/0 refuse
77+
78+
79+
# Block HTTPS (TYPE65/ECH) records for local domains.
80+
# Cloudflare publishes HTTPS records with ECH params for proxied domains. When
81+
# PiHole returns local IPs for these domains, Chrome/Safari try to use those
82+
# Cloudflare ECH params against the local server, causing ERR_SSL_PROTOCOL_ERROR.
83+
# A 'static' zone returns NXDOMAIN for any RR type not explicitly defined via
84+
# local-data. Since we define no local-data here, all TYPE65 queries get NXDOMAIN.
85+
# A record lookups for these domains are handled upstream by PiHole (address=
86+
# directives) and never reach Unbound, so this does not affect normal resolution.
87+
local-zone: "geeksbsmrt.com." static
88+
local-zone: "smrtgeekdevs.com." static

0 commit comments

Comments
 (0)