Private DNS with MagicDNS

Using Tailscale and MagicDNS to create a private DNS setup

Brad Fitzpatrick and David Crawshaw on
Photo of Brad Fitzpatrick
Photo of David Crawshaw

One of Tailscale’s features is called MagicDNS. Its main visible feature is that it lets you access all the nodes on your Tailnet by their names instead of the Tailscale IPs.

That may not sound particularly new; after all, DNS maps names to numbers. Systems like mDNS even do it automatically. What is interesting about MagicDNS is how it can do so securely, without name lookup information leaving your device, and how it can upgrade the security of non-Tailscale DNS queries.

The current state of DNS security

But first, why are we concerned about DNS security at all? What does that even mean? Why would it be insecure?

It all dates back to the early days of the Internet (back when it was capitalized) when people largely trusted each other, or at least didn’t know better to not trust each other. Maybe they were more focused on getting computers talking at all rather than worrying about security.

In any case, early DNS was not encrypted or authenticated. Anybody on your network or along its path could see your DNS queries or modify their responses. You might think today’s internet has since fixed all that insecurity and DNS is secure now. And you would be wrong. Change takes time, especially when it comes to changing big moving Rube Goldberg machines like the internet.

But there’s been progress.

A reductive history of DNS through the ages, so you don’t need to read a few dozen RFCs:

Ignoring DNSSEC:

Cold start round-trips 1 3-4 1-2 more Same as DoT; better with QUIC
Security - - TLS TLS
HTTP? - - - yes
Client/OS support everything nearly everything minimal browsers, the new OSes

How MagicDNS works

Tailscale runs a DNS server built-in on every node, running at

Yes, Tailscale on your phone includes a DNS server. (We admit that “even on your phone!” is a little silly when phones are basically supercomputers these days.)

The IP, usually pronounced “quad one hundred,” is part of the private Carrier-Grade NAT range. That means, just like IPs in the common private ranges, 192.168.1/24, 172.16/12, and 10/8, it is not routable on the public internet. So when software on your computer sends a traditional, unencrypted UDP packet to, no standard router will send it anyway.

We then tell your OS that its DNS server is Because operating system DNS clients are largely stuck in 1987, they then forward all their DNS queries over old-school insecure UDP DNS to Tailscale also installs a route to back into Tailscale and it then hands those packets over to Tailscale’s built-in DNS server, so unencrypted queries don’t leave your device.

Push, not pull

Now it is time for MagicDNS to answer queries. For resolving public domains (e.g. “”) the local Tailscale process will forward the query onto whatever name server your OS was originally configured with, or whatever name server you override it within your Tailscale admin settings. For looking up private names on your tailnet: the query goes nowhere! Instead, when your local Tailscale is configured with a map of your tailnet, it is pushed all of the private DNS names your computer has access to. In addition to there being no external service that can log your private name lookups, there is an extra benefit to a push-based DNS database for small networks (where “small” means “not billions”): no TTL.

In standard DNS, every query response includes a Time To Live (TTL). Your local computer, and other, usually helpful, intermediaries like your local network router will store a copy of a query response for however long the TTL says it can. Your subsequent queries look in the stored cache and if the record has not expired yet, no new lookup is done.

That is great for saving bandwidth and more importantly, latency when you use a program that makes many separate connections to the same destination. But it has a downside: if you change your DNS records for a domain, they don’t propagate completely until the TTL has expired in all the cached resolvers around the internet. That is fine for large public sites, there are several workarounds engineers use to change records slowly without breaking anyone. But it can be extremely annoying when configuring and reconfiguring your own personal network. We want to see changes immediately. That is a benefit to the push-based approach: as soon as you change your tailnet, by adding a host or editing a name, the new network map is immediately sent to every computer in your tailnet and the new name is there ready to go. No need to think about caching resolvers in home internet routers.

Fun with MagicDNS

Once the MagicDNS resolver has the queries, we can do fun things:

Future work

MagicDNS is still in beta because we’re not entirely done with all the features we’d like to add and fixing the long tail of OS integrations (it can be a nightmare).

Some of the features we’re exciting about adding:

Try it out

To enable MagicDNS, go to the DNS settings of the admin console at and click “Enable MagicDNS”.

If you’re using Split DNS, the built-in MagicDNS resolver won’t be used unless it’s needed to resolve a name in your Tailnet. To force your clients to use DoH for their upstream queries, you can click “Override local DNS” and set a global nameserver to Google (, Cloudflare (, or Quad9 ( IPs.

Individual devices can opt-out of the Tailnet-wide DNS settings by opening the Tailscale app and unchecking “Use Tailscale DNS Settings” under “Preferences” or using the tailscale up --accept-dns=false option on the CLI.

Your nodes are assigned automatic DNS names based on their hostnames, adding numeric suffixes as needed to resolve conflicts. To change their DNS names, go to the machines page in the admin console, click the three dots on the right of a device to rename, and choose “Edit machine name…”

Subscribe for monthly updates

Product updates, blog posts, company news, and more.

Too much email? RSS Twitter