Tailscale is a fantastic tool for securely accessing all your systems and applications remotely. However, it does come with some trade-offs — especially when it comes to DNS. By default, Tailscale takes over your system’s DNS settings. While non-Tailscale domains are generally forwarded to your local resolver, that behavior depends on Tailscale functioning correctly.
Recently, I ran into an issue where one of my nodes had an expired key and couldn’t connect to the tailnet anymore. As a result, all DNS queries on that system failed, even for unrelated domains.
While this might have been a rare edge case, it made me wonder: Can I configure my system to only use Tailscale’s DNS (100.100.100.100) for .ts.net domains, while keeping my normal DNS resolver for everything else?
The answer is yes — by using systemd-resolved, you can set up true split DNS and direct specific domains like *.ts.net to Tailscale’s DNS while keeping everything else on your local DNS.
Install systemd-resolved
First, ensure that systemd-resolved is installed and enabled on your system:
1sudo apt update
2sudo apt install systemd-resolved
3sudo systemctl enable systemd-resolved
4sudo systemctl start systemd-resolved
Also, make sure /etc/resolv.conf is pointing to the systemd stub resolver:
1sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
Create Tailscale DNS Split Configuration
To configure systemd-resolved to use Tailscale’s DNS server only for .ts.net domains, we’ll create a network configuration file that is applied at boot.
Open the file:
1sudo nano /etc/systemd/network/99-tailscale.network
Paste the following:
1[Match]
2Name=tailscale0
3
4[Network]
5DNS=100.100.100.100
6Domains=~ts.net
This tells systemd-resolved to use 100.100.100.100 (Tailscale’s MagicDNS) only for .ts.net
queries on the tailscale0 interface.
Apply the changes by restarting the systemd network daemon:
1sudo systemctl restart systemd-networkd
After setting up split DNS with systemd-resolved, you can use the resolvectl status
command to confirm that your system is routing DNS queries correctly.
In the example below, you can see that:
- The default DNS resolver is your local network DNS (192.168.1.1 on eth0)
- Tailscale’s DNS server (100.100.100.100) is only used for .ts.net domains and associated reverse zones on the tailscale0 interface
1Global
2 Protocols: +LLMNR +mDNS -DNSOverTLS DNSSEC=no/unsupported
3resolv.conf mode: uplink
4
5Link 2 (eth0)
6 Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6
7 Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
8Current DNS Server: 192.168.1.1
9 DNS Servers: 192.168.1.1
10 DNS Domain: home
11
12Link 3 (tailscale0)
13 Current Scopes: DNS
14 Protocols: -DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
15Current DNS Server: 100.100.100.100
16 DNS Servers: 100.100.100.100
17 DNS Domain: tail43c135.ts.net ~0.e.1.a.c.5.1.1.a.7.d.f.ip6.arpa ~100.100.in-addr.arpa ~101.100.in-addr.arpa
18 ~102.100.in-addr.arpa ~103.100.in-addr.arpa ~104.100.in-addr.arpa ~105.100.in-addr.arpa ~106.100.in-addr.arpa
19 ~107.100.in-addr.arpa ~108.100.in-addr.arpa ~109.100.in-addr.arpa ~110.100.in-addr.arpa ~111.100.in-addr.arpa
20 ~112.100.in-addr.arpa ~113.100.in-addr.arpa ~114.100.in-addr.arpa ~115.100.in-addr.arpa ~116.100.in-addr.arpa
21 ~117.100.in-addr.arpa ~118.100.in-addr.arpa ~119.100.in-addr.arpa ~120.100.in-addr.arpa ~121.100.in-addr.arpa
22 ~122.100.in-addr.arpa ~123.100.in-addr.arpa ~124.100.in-addr.arpa ~125.100.in-addr.arpa ~126.100.in-addr.arpa
23 ~127.100.in-addr.arpa ~64.100.in-addr.arpa ~65.100.in-addr.arpa ~66.100.in-addr.arpa ~67.100.in-addr.arpa
24 ~68.100.in-addr.arpa ~69.100.in-addr.arpa ~70.100.in-addr.arpa ~71.100.in-addr.arpa ~72.100.in-addr.arpa
25 ~73.100.in-addr.arpa ~74.100.in-addr.arpa ~75.100.in-addr.arpa ~76.100.in-addr.arpa ~77.100.in-addr.arpa
26 ~78.100.in-addr.arpa ~79.100.in-addr.arpa ~80.100.in-addr.arpa ~81.100.in-addr.arpa ~82.100.in-addr.arpa
27 ~83.100.in-addr.arpa ~84.100.in-addr.arpa ~85.100.in-addr.arpa ~86.100.in-addr.arpa ~87.100.in-addr.arpa
28 ~88.100.in-addr.arpa ~89.100.in-addr.arpa ~90.100.in-addr.arpa ~91.100.in-addr.arpa ~92.100.in-addr.arpa
29 ~93.100.in-addr.arpa ~94.100.in-addr.arpa ~95.100.in-addr.arpa ~96.100.in-addr.arpa ~97.100.in-addr.arpa
30 ~98.100.in-addr.arpa ~99.100.in-addr.arpa ~ts.net
The long list of ~100.in-addr.arpa entries is used for reverse DNS (PTR) lookups in Tailscale’s subnet.
Testing Resolution
Use resolvectl query to check which DNS server is used per domain:
Query a public domain (uses local DNS):
1resolvectl query google.com
1google.com: 172.217.23.206 -- link: eth0
2 2a00:1450:400e:802::200e -- link: eth0
3
4-- Information acquired via protocol DNS in 8.3ms.
5-- Data is authenticated: no; Data was acquired via local or encrypted transport: no
6-- Data from: network
Query a Tailscale domain (uses Tailscale DNS):
1resolvectl query beszel.tail43c135.ts.net
1beszel.tail43c135.ts.net: 100.80.20.240 -- link: tailscale0
2
3-- Information acquired via protocol DNS in 4.2ms.
4-- Data is authenticated: no; Data was acquired via local or encrypted transport: no
5-- Data from: network