Look, I'm not trying to sell my solution here. This is Hacker News, I'm simply share my setup and hope can help someone who's capable and willing to invest the time. I understand this is not for everyone, that's why I suggest nextdns.io as hosted solution in the README.
That sounds like a pretty good reason not to run your own solution then, so I guess we can meet there.
> Look, I'm not trying to sell my solution here.
Yes, you are.
This project seems to occupy the same niche as products like Blokada. Most of the benefits of a self hosted solution, with a much lower barrier to entry.
Well done.
Docker compose file makes everything easily reproducible and I've included working example configs. Not sure how I can further simplify the setup but open to suggestions.
The most useful option I've seen for trying to get the benefits of both has been rotating between a list of DoT resolvers, so none get all the history and end up with fragmented profiles. There's issues there since people access the same services and thus they'll get the full list over time if the software doesn't record who got what request and stickies it to them. There's always the option of doing it over Tor, but then you're introducing multisecond latencies to your DNS queries, which isn't exactly a great experience.
So because a snooping provider is irrelevant when we talk only about resolving DNS, that only leaves the choice of which party to the chain of entities that are able to easily snoop on your or not. If privacy is important, adding Google or any other DoT resolver to that chain is strange.
Second, Google uses personal data combined with machine learning to optimize "user engagement" (roughly, hours spent on the service) because that has been proven to be a good predictor for how resistant an internet service is to competition or disruption. This optimization of user engagement has a bad effect on the productivity and perhaps the mental health of individuals and families and has a bad effect on our public discourse.
Even with this setup there are ways to increase reliability with-in the budget/skill set of a normal engineer, e.g. run two RasPi with keepalived and run VRRP on your routers. As a last resort, I can disable the "Private DNS" setting on my phone if my DNS is down and I can't fix quickly enough remotely.
From a networking perspective, getting VRRP working on anything but physical equipment (e.g. in the cloud) is a fool's errand; it's L7/API-based and not on the ethernet level. Similarly with keepalived, which will get isolated from the monitored instances (thereby failing to the other, also "down" instance) — except it might have access to the API gateway of the cloud provider thereby disassociating the V-IP from both your instances; so you'll end up with more downtime with keepalived than you gain by it.
Since DNS is by default inconsistent, but eventually consistent and thereby possible to load-balance, you could run one instance of this stack on your static home IP and another instance on GCP/DO/AWS and configure multiple DNS servers in your DHCP options and on your phone, to get higher availability.
Implementing the whole thing (modulo the anycast IP, which is the only thing I did not use) is easy. I have a docker-compose file which does the whole stack:
1. Unbound DNS which provides DNS-over-TLS service at port 853. It forward request to my local pihole's 53 port. 2. Pihole forward request to my Stubby DNS server. 3. Stubby connects to Google DNS over DNS-over-TLS. 4. A separate docker container to run certbot to update certificate used by the unbound container. 5. A separate docker container with Pomerium as reverse proxy so I can remote access PiHole UI.
Then you can configure your Android phone to use your unbound DNS server as the "private DNS" server. I've being using this setup for more than a month and works really well.
UPDATE: I posted my docker-compose.yaml file at https://github.com/yegle/your-dns. I'll update the README soon.