Hosting your own authoritative DNS servers using PowerDNS

Bluemedia (Oliver) | Dec 22, 2021 min read

Intro

A quick disclaimer at first: This post is not intended to be a complete guide on how to build your own system. It is more intended as an example of how I solved my personal requirements. PowerDNS is a very powerful tool and offers many ways to solve problems in different ways. In the end, everyone has to decide for themselves what they think is an ideal configuration and whether they want to leave it to the “big bad internet” like this.

Should you run your own authoritative DNS servers?
In most cases, probably not.
Am I doing it anyway?
Of course I do.
Why, you may ask?
Because I can, and it’s a good way to learn more about DNS.

I’m generally a big fan of having important services under my own control, as you may have noticed already from some other posts. This allows me to customize them exactly as I want to. My infrastructure is mostly automated, so I don’t have to waste my free time on maintaining it. Unfortunately, my registrar, where I get almost all my domain names, doesn’t have a particularly great API for managing DNS records. This is, of course, a problem in such a case.

Because of this, I’ve been using Cloudflare as my DNS provider for a while now. The free package with the included features is quite usable, and they have a really great API. After the second major outage of Cloudflare, however, I realized that it might not be the best idea to make half of the Internet depend on one provider. For this reason and also because I’m generally interested in the topic from a technical perspective, it ended up on my to-do list at some point.

Starting off with a plan

So what are the things you need to consider if you really want to run such a service yourself?

In my opinion, you should know what you are doing before you actually start doing it. Accordingly, the topic has started for me by first reading up on “best practices” for DNS and the documentation of my desired software (PowerDNS) over a good cup of coffee. While doing so, a more or less finished concept formed in my head, which I’m fairly certain is perfectly acceptable as is.

Based on my initial starting position, I knew it had to be highly available, fault-tolerant, and relatively inexpensive. These things are not necessarily opposed to each other here.

To meet my requirements, I’m using two small servers at different providers (Hetzner and Netcup) located at different sites (Nuremberg and Falkenstein). Furthermore, because both servers are in different top-level domains (.dev and.re), even the theoretical failure of an entire top-level domain can be compensated.

Each server runs a MariaDB instance and PowerDNS with a minimal configuration. NS1 is the primary system, which is also used for administration. NS2 hosts a read-only replica of the PowerDNS database and PowerDNS itself. Both externally accessible PowerDNS instances have read-only access to the database and no enabled special functions, such as the HTTP API. They merely act as “dumb” resolvers.

On NS1, there is also another PowerDNS instance running inside Docker, this time with write access to the database and an enabled HTTP API, as well as an instance of PowerDNS-Admin for the actual administration. From the outside, PowerDNS-Admin is accessible via an Nginx reverse proxy that takes care of things like TLS termination and logging. Both servers are connected by a WireGuard tunnel for the MariaDB replication traffic.

PowerDNS-Admin is a comprehensive administration toolkit for PowerDNS. It provides full multi-tenancy in terms of zone management and can manage API keys restricted to individual zones. It also provides a well-organized web interface for the overall administration.

This is how my finished concept looks on the drawing board:

Keeping security in mind

If you operate such a service publicly, you should also take some time to think about security. After all, you don’t want your own infrastructure to be immediately taken over by the next best troll or abused for DDoS.

Therefore, it is necessary to think about the following rules:

  • Only absolutely necessary services should be accessible from external sources
  • Systems must be protected against unauthorized access (e.g., SSH only via public key authentication)
  • Always use strong passwords and 2FA everywhere (in this case, PowerDNS-Admin)
  • All software should be kept up-to-date and patches should be installed in a timely manner after their release

With DNS, there are some additional things that will save you and others from trouble:

  • Both PowerDNS instances are authoritative-only and do not allow recursive queries
  • Zone transfer (AXFR) should be disabled if not required, or at least restricted to certain IPs. This prevents all DNS entries (entire zones) from being retrieved at once
  • You should configure appropriate rate limits in PowerDNS to make it as difficult as possible for attackers to abuse your servers for DNS reflection attacks (DDoS amplification)

Conclusion

With a bit of ingenuity, the right planning, and the relevant documentation, an idea like this can certainly become a reality. This opens up countless possibilities to customize the system to your own needs. You need an additional DNS server? Just set up another replica. If necessary, all of this can also be automated.

By now, I’ve been running my two DNS servers productively for almost two months and have already survived the first failures without any problems. Both servers were offline for a short period of time due to problems with their respective host systems, but due to the separation of the two instances, it was still possible to resolve the domains at any time.

Because PowerDNS is very resource-saving and I don’t expect many DNS requests anyway, I can use the smallest server size that the respective hosting company offers. This brings my total cost to about 6 euros per month, which is still quite impressive in my opinion.