AdGuard Home

AdGuard Home is an open source and free self hosted DNS server that comes with an easy way to prevent resolution of domains serving ads, trackers, malware, and other unwanted content.

Setup

AdGuard did a good job at making setup of AdGuard Home easy. They provide a Snap package of the server. You install that, then walk through a web installer that gets everything set up for you. I additionally wanted to use DNS over TLS to allow secure resolution (and the ability to set it as the resolver for all networks on Android), which was easy to do through AdGuard Home's web UI since I already had a TLS certificate I made for hosting Nextcloud for my family.
AdGuard allows you to pick out what filters you want to use for your connection. There are some default selections made, but I customized the list of filter lists to cover as much as possible, while working with my family to find lists with false positives and remove them. After some iteration I came to a selection that does not block anything useful, while cutting out a decent portion of ads.

Troubleshooting

Sadly, it is rare for something to work completely perfectly out of the box, and AdGuard Home is not an exception. I ran into some issues while using it, but have been able to correct them.

IPv6 and NAT64

A bit after getting AdGuard Home up and working, my parents bought me a new phone to have for university since my current one was having battery problems. This was my first 5G network phone, which let me discover my first issue with my DNS server.
5G is different from previous generations of cell networks in that it uses IPv6 exclusively. While this should not be a problem, a lot of other ISPs are still running IPv4 only networks. T-Mobile mitigates this by using NAT64, a technique that involves replacing the AAAA responses from domains that do not have AAAA records with an AAAA record meant to indicate to the network that the traffic should be relayed to a certain IPv4 address instead of sent through to the IPv6 internet. This replacement is called DNS64, which T-Mobile's DNS servers did, but mine did not. This caused a bunch of things to stop connecting whenever I was on cell data, which was very problematic.
Once I worked out that my phone wasn't able to connect directly to IPv4 on cell data and that was the cause of my issues, I looked for a solution to make my DNS server DNS64 compatible so that I could still use the internet on cell data. Luckily, AdGuard makes a program called DNS Proxy, which was able to do the DNS64 translation needed for NAT64 to work. I put DNS Proxy in front of AdGuard Home, and everything now worked.
Eventually AdGuard included DNS64 functionality directly in AdGuard Home, which allowed me to remove DNS Proxy from my setup and simplify things a little.

Redundancy

Having a working connection to a DNS server is mandatory to use the modern internet, so any downtime on my single AdGuard Home server resulted in everything else I owned losing the ability to connect to most of the internet. This is incredibly annoying, especially when trying to use the internet to troubleshoot a problem with the server AdGuard Home is running on.
The solution to this was to expand horizontally and add in a second AdGuard Home server. This meant that if one of them died for some reason, the other could take on the DNS traffic and let me keep a working internet connection while I tried to figure out what the problem was. To do this, I decided to supplement my donated server with a cloud server from Digital Ocean, which generously provides a large amount of credits to students to use via the GitHub Student Developer Pack. Doing the initial setup of the VPS on Digital Ocean was a straightforward process, and after I was able to go through installing AdGuard Home. I changed the DNS records I was using to connect to include the new Digital Ocean server, and everything worked fine for a while.
Every 3 months, the servers need to renew a security certificate to provide an encrypted connection. I had this process automated using ACME, however what I didn't think of when I was setting up the second server is how ACME would react to there being two IP addresses serving a single domain. ACME handles this by requiring the ACME process to succeed on all IP addresses hosting a domain, which I had not set up. This ended up in me hitting the loss of working internet connection problem I was trying to avoid when the certificate eventually expired. The fix was relatively easy; I switched from using a TLS challenge to prove control of the domain to an HTTP challenge, and set up a redirect on the Digital Ocean server to send ACME challenge traffic to the self hosted server. This fixed the problem, and served as a bit of a learning experience on one of the security decisions the designers of ACME made.