In unbound those are indeed views[1]. I moved from pihole to unbound+nsd a couple of years ago for precisely this use case. Block filters courtesy of[2].
I managed this by getting a gTLD (digit-only .xyz is cheapest) for internal-only services and then running a Caddy instance to reverse-proxy to my internal services. I don't port forward or open ports to that Caddy instance, so it's not available externally.
I wish pihole or adguard would add support for change DNS records based on the query subnet. I believe this is called DNS views.
That way my local devices and wireguard devices can get the correct IP for internal services.