Help troubleshooting https-dns-proxy with iCloud Private Relay

My goal is to allow iCloud Private Relay (and other programs with their own secure DNS) to function normally, and use OpenWrt to apply secure dns to everything else.

Q1) Is iCloud Private Relay supposed to work with https-dns-proxy?
Q2) If not, is there a recommended alternative package?

Symptoms:
A) Starting with a fresh installation of OpenWrt, iCloud Private Relay works.
B) After installing https-dns-proxy and luci-app-https-dns-proxy, iCloud Private Relay doesn't work.
C) After stopping/disabling https-dns-proxy, iCould Private Relay still doesn't work. Re-tested after rebooting both OpenWrt and MacOS, still doesn't work.
D) After re-starting https-dns-proxy and setting "option canary_domains_icloud '0'" and "option force_dns '0'", iCloud Private Relay still doesn't work. Also re-tested after rebooting both router and client.

Repeated the above sequence multiple times.

Q3) Are there other settings I should change?


root@OpenWrt:~# ubus call system board

{
	"kernel": "6.12.74",
	"hostname": "OpenWrt",
	"system": "Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz",
	"model": "Default string Default string",
	"board_name": "default-string-default-string",
	"rootfs_type": "ext4",
	"release": {
		"distribution": "OpenWrt",
		"version": "25.12.2",
		"firmware_url": "https://downloads.openwrt.org/",
		"revision": "r32802-f505120278",
		"target": "x86/64",
		"description": "OpenWrt 25.12.2 r32802-f505120278",
		"builddate": "1774469393"
	}
}

root@OpenWrt:~# curl -V
-ash: curl: not found


root@OpenWrt:~# dnsmasq --version

Dnsmasq version 2.91  Copyright (c) 2000-2025 Simon Kelley
Compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-nftset no-auth no-DNSSEC no-ID loop-detect inotify dumpfile

root@OpenWrt:~# https-dns-proxy -V

2025.12.29-r4
Using: ev/4.33 c-ares/1.34.6 libcurl/8.19.0 mbedTLS/3.6.6 nghttp2/1.66.0
Features: HTTP2 HTTPS-proxy IPv6

root@OpenWrt:~# uci export dhcp

package dhcp

config dnsmasq
	option domainneeded '1'
	option localise_queries '1'
	option rebind_protection '1'
	option rebind_localhost '1'
	option local '/lan/'
	option domain 'lan'
	option expandhosts '1'
	option cachesize '1000'
	option authoritative '1'
	option readethers '1'
	option leasefile '/tmp/dhcp.leases'
	option localservice '1'
	option ednspacket_max '1232'
	list server '/mask.icloud.com/'
	list server '/mask-h2.icloud.com/'
	list server '/use-application-dns.net/'
	list server '127.0.0.1#5053'
	list server '127.0.0.1#5054'
	list rebind_domain 'mask.icloud.com'
	list rebind_domain 'mask-h2.icloud.com'
	list rebind_domain 'use-application-dns.net'
	option doh_backup_noresolv '-1'
	option noresolv '1'
	list doh_backup_server '/mask.icloud.com/'
	list doh_backup_server '/mask-h2.icloud.com/'
	list doh_backup_server '/use-application-dns.net/'
	list doh_backup_server '127.0.0.1#5053'
	list doh_backup_server '127.0.0.1#5054'
	list doh_server '127.0.0.1#5053'
	list doh_server '127.0.0.1#5054'

config dhcp 'lan'
	option interface 'lan'
	option start '100'
	option limit '150'
	option leasetime '12h'
	option dhcpv4 'server'
	option dhcpv6 'server'
	option ra 'server'
	option ra_slaac '1'
	list ra_flags 'managed-config'
	list ra_flags 'other-config'

config dhcp 'wan'
	option interface 'wan'
	option ignore '1'

config odhcpd 'odhcpd'
	option maindhcp '0'
	option leasefile '/tmp/odhcpd.leases'
	option leasetrigger '/usr/sbin/odhcpd-update'
	option loglevel '4'
	option piodir '/tmp/odhcpd-piodir'
	option hostsdir '/tmp/hosts'

root@OpenWrt:~# uci export network

package network

config interface 'loopback'
	option device 'lo'
	option proto 'static'
	list ipaddr '127.0.0.1/8'

config globals 'globals'
	option dhcp_default_duid '00042f1274a2ceb342aab25d0376919607ce'
	option ula_prefix 'fdca:eec3:e60d::/48'

config device
	option name 'br-lan'
	option type 'bridge'
	list ports 'eth0'

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	list ipaddr '192.168.2.1/24'
	option ip6assign '60'

config interface 'wan'
	option device 'eth1'
	option proto 'dhcp'

config interface 'wan6'
	option device 'eth1'
	option proto 'dhcpv6'

root@OpenWrt:~# uci export https-dns-proxy

package https-dns-proxy

config main 'config'
	option dnsmasq_config_update '*'
	option force_dns '0'
	list force_dns_port '53'
	list force_dns_port '853'
	list force_dns_src_interface 'lan'
	option procd_trigger_wan6 '0'
	option heartbeat_domain 'heartbeat.melmac.ca'
	option heartbeat_sleep_timeout '10'
	option heartbeat_wait_timeout '10'
	option user 'nobody'
	option group 'nogroup'
	option listen_addr '127.0.0.1'

config https-dns-proxy
	option bootstrap_dns '1.1.1.1,1.0.0.1'
	option resolver_url 'https://cloudflare-dns.com/dns-query'
	option listen_port '5053'

config https-dns-proxy
	option bootstrap_dns '8.8.8.8,8.8.4.4'
	option resolver_url 'https://dns.google/dns-query'
	option listen_port '5054'

root@OpenWrt:~# service https-dns-proxy status
running


root@OpenWrt:~# service https-dns-proxy info

{
	"https-dns-proxy": {
		"instances": {
			"instance1": {
				"running": true,
				"pid": 10985,
				"command": [
					"/usr/sbin/https-dns-proxy",
					"-r",
					"https://cloudflare-dns.com/dns-query",
					"-p",
					"5053",
					"-b",
					"1.1.1.1,1.0.0.1",
					"-4",
					"-u",
					"nobody",
					"-g",
					"nogroup"
				],
				"term_timeout": 5,
				"data": {
					"mdns": {
						"https-dns-proxy_5053": {
							"service": "_https-dns-proxy._udp.local",
							"port": 5053,
							"txt": [
								"DNS over HTTPS proxy"
							]
						}
					}
				},
				"respawn": {
					"threshold": 3600,
					"timeout": 5,
					"retry": 5
				}
			},
			"instance2": {
				"running": true,
				"pid": 10986,
				"command": [
					"/usr/sbin/https-dns-proxy",
					"-r",
					"https://dns.google/dns-query",
					"-p",
					"5054",
					"-b",
					"8.8.8.8,8.8.4.4",
					"-4",
					"-u",
					"nobody",
					"-g",
					"nogroup"
				],
				"term_timeout": 5,
				"data": {
					"mdns": {
						"https-dns-proxy_5054": {
							"service": "_https-dns-proxy._udp.local",
							"port": 5054,
							"txt": [
								"DNS over HTTPS proxy"
							]
						}
					}
				},
				"respawn": {
					"threshold": 3600,
					"timeout": 5,
					"retry": 5
				}
			}
		},
		"triggers": [
			[
				"interface.*",
				[
					"if",
					[
						"eq",
						"interface",
						"wan"
					],
					[
						"run_script",
						"/etc/init.d/https-dns-proxy",
						"reload",
						"on_interface_trigger"
					]
				],
				1000
			],
			[
				"config.change",
				[
					"if",
					[
						"eq",
						"package",
						"https-dns-proxy"
					],
					[
						"run_script",
						"/etc/init.d/https-dns-proxy",
						"reload",
						"on_config_change"
					]
				],
				1000
			]
		]
	}
}

root@OpenWrt:~# nslookup google.com 127.0.0.1:5053

Server:		127.0.0.1:5053
Address:	127.0.0.1:5053

Non-authoritative answer:
Name:	google.com
Address: 142.251.35.78

Non-authoritative answer:
Name:	google.com
Address: 2607:f8b0:4007:80c::200e

this should kill DNS name resolution completely, if configured correctly.

do nslookups of mask.icloud.com and mask-h2.icloud.com on the client while rerunning your tests, post the results (including actual output from nslookup).

Requested results pasted below.
I got iCloud Private Relay working by removing mask.icloud.com and mask-h2.icloud.com from the DNS Forwards section in the Network | DNS section of OpenWrt's web app. I didn't put the Forwards there, they were a result of installing https-dns-proxy.
Also, the Forwards remained after stopping https-dns-proxy. I read here that https-dns-proxy modifies settings outside itself, then restores them when stopped. I don't know if this is supposed to apply to all dnsmasq settings, but I noticed several settings changing as I progressed through the stages below. I tried to capture them at each stage, can supply the files separately if they'd be useful.

Here're the results from running nslookup mask.icloud.com from Mac client after each change.
nslookup mask-h2.icloud.com matched mask each time, not pasted here.

  1. Fresh OpenWrt install, before installing https-dns-proxy
Server:		192.168.2.1
Address:	192.168.2.1#53

Non-authoritative answer:
mask.icloud.com	canonical name = mask.apple-dns.net.
Name:	mask.apple-dns.net
Address: 17.248.171.6
Name:	mask.apple-dns.net
Address: 17.248.171.34
Name:	mask.apple-dns.net
Address: 17.248.188.114
Name:	mask.apple-dns.net
Address: 17.248.171.39
Name:	mask.apple-dns.net
Address: 17.248.174.44
Name:	mask.apple-dns.net
Address: 17.248.171.11
Name:	mask.apple-dns.net
Address: 17.248.171.38
Name:	mask.apple-dns.net
Address: 17.248.171.10
  1. After installing https-dns-proxy
Server:		192.168.2.1
Address:	192.168.2.1#53

** server can't find mask.icloud.com: NXDOMAIN
  1. After stopping https-dns-proxy
Server:		192.168.2.1
Address:	192.168.2.1#53

Non-authoritative answer:
mask.icloud.com	canonical name = mask.apple-dns.net.
Name:	mask.apple-dns.net
Address: 17.248.171.52
Name:	mask.apple-dns.net
Address: 17.248.171.51
Name:	mask.apple-dns.net
Address: 17.248.171.8
Name:	mask.apple-dns.net
Address: 17.248.171.50
Name:	mask.apple-dns.net
Address: 17.248.171.37
Name:	mask.apple-dns.net
Address: 17.248.171.35
Name:	mask.apple-dns.net
Address: 17.248.171.10
Name:	mask.apple-dns.net
Address: 17.248.171.4
  1. After starting and disabling force_dns
Server:		192.168.2.1
Address:	192.168.2.1#53

** server can't find mask.icloud.com: NXDOMAIN
  1. After removing DNS Forwards for mask.icloud.com and mask-h2.icloud.com.
    First removed the forwards with a running https-dns-proxy. They came back after stopping https-dns-proxy. So removed them again, and now they seem gone for good. After re-starting https-dns-proxy, iCloud Private Relay is working.
Server:		192.168.2.1
Address:	192.168.2.1#53

Non-authoritative answer:
mask.icloud.com	canonical name = mask.apple-dns.net.
Name:	mask.apple-dns.net
Address: 17.248.171.39
Name:	mask.apple-dns.net
Address: 17.248.171.9
Name:	mask.apple-dns.net
Address: 17.248.171.35
Name:	mask.apple-dns.net
Address: 17.248.171.51
Name:	mask.apple-dns.net
Address: 17.248.171.4
Name:	mask.apple-dns.net
Address: 17.248.188.115
Name:	mask.apple-dns.net
Address: 17.248.171.37
Name:	mask.apple-dns.net
Address: 17.248.174.44