For blocking I use Pi-hole https://pi-hole.net/ and unbound. I like the simple interface of the the Pi-Hole, point it to the locally running unbound which is configured to use several DoH providers I trust.
Well, since its main use case is with a stand-alone Raspberry Pi, this shouldn’t be too much of an issue. Just treat it as an appliance, like a router.
I use Unbound in a similar way, although I return 0.0.0.0 rather than NXDOMAIN. Don't really know why I decided to go that route, but when I was setting my Unbound server up I'd read how quad 0's was the pi-hole's preferred setting [0]. Seems the articles' script would accept such a setup too, via the ${TYPE} parameter (or maybe a slight rewrite of the `echo` later on there).
Not sure which one is safer but I have read in many places that using NXDOMAIN is a lot faster then 127.0.0.1/0.0.0.0 because with NXDOMAIN you get 'fail' instantly while with 127.0.0.1/0.0.0.0 you need to wait for connection timeout.
I do the same for the same reasons, pi-hole docs recommends 0.0.0.0.
I am wondering if you have multiple resolvers set up on a client, if you receive an nxdomain response if it will attempt another resolver? Which wouldn’t be what you want to happen with a block list.
I configured Firefox to use my local DoH server instead. That way I don't have to fight against DoH, I get the (few) benefits of ESNI and can still choose what my upstream servers will be. Your solution is also good and it is what we configured at work (through group policies). You or someone else reading may find this[1] and this[2] useful.
I don't know, I'm not the one who reported that issue and I use a local DoH server, that way I make sure that when Firefox uses DoH I still have full control over it.
I used to do something like this with knot-resolver, but now I just use NextDNS. It's really nice to have separate profiles so that my IoT devices get extremely strict blocking, while my personal devices can be slightly more lax to avoid false positives.
I did not had any earlier config so I started fresh but nothing stops you from using just the script for generating additional *.conf file for your current unbound(8) setup.