Rewrite dns domain with adguard

so i have set up a adguard server as the dns for tailscale, and it works pretty well.

but i would like to be able to change the domain i get from tailscale, to something that is simpler to remember. like *.tail
i have gotten it to work for connecting to specific servers, but it would be nice to have a catch all rule so i don’t have to set it up each time i set up a new server.

adguard has some functionality to rewrite dns-responses, but i’ve not been able to get it to work. does anyone have any insight into how it has to be set up or if it’s even possible?

i’ve tried to set it up in the rewrite tab, and in the custom rules tab:
custom rule: ||tail^$dnsrewrite=NOERROR;CNAME;<tailscale domain>

I’m not too familiar with AdGuard’s DNS features, but doesn’t their DNS service reside on the internet?
Because if that’s indeed the case (as opposed to running locally on your LAN) then once the DNS request is on the internet, you can’t have AdGuard’s DNS service (rewrite and) forward the request to your tailnet’s DNS server, as the public AdGuard DNS server doesn’t have access to your tailnet.

A simple way I can think of at the moment would be to start your own DNS service in your LAN that will resolve *.tail addresses. Then you create a split DNS entry in the Tailscale admin console where all requests to the "tail" domain will go to your own DNS server, which will then resolve it to the respective tailscale IP.

Edit: Mind you though, I’m actually not quite sure if the handing off of the DNS request from AdGuard’s DNS server to your tailnet’s DNS server happens directly from AdGuard. Could be that AdGuard simply tells your browser to repeat the request, which then should indeed work, as your browser (i.e. your device) is on the tailnet.

In that case you’d have to:

  • Tell AdGuard to rewrite *.tail to *.<YOUR_TAILNET>.ts.net (you’ve already done that it looks like)
  • Tell AdGuard to redirect such requests (after the rewrite) to your tailnet’s DNS server.
    (Note: If rewriting and redirecting doesn’t work together, then you’d have to still setup a custom DNS service on your LAN that can resolve *.tail requests and have AdGuard simply redirect all *.tail requests there without prior rewriting.)

I’m not sure if you can do the latter, but that would be a required step.

i’m running the adguard server locally in my home lab cluster, with tailscale running on that server and the dns settings set to override dns on all connected tailscale clients.

I looked at the AdGuard documentation just now. I’m assuming you’re using AdGuard private DNS then, right? Your rewrite rule looks fine to me.

What does a nslookup say when you try to resolve a *.tail domain?

Just to rule out a problem with detection of subdomains (when using a TLD as the domain in the rule), try this entry instead (just temporarily):
||something.tail^$dnsrewrite=NOERROR;CNAME;<tailscale domain>

Then try and see if something.tail gets resolved. If it does, then we might just need to adjust the incoming domain detection part of the rule.

okay. thanks for trying to figure this out with me.

i set this rule: ||test.tail^$dnsrewrite=NOERROR;CNAME;<hostname>.<subdomain>.ts.net and i get this with nslookup:

$ sudo resolvectl flush-caches

$ nslookup test.tail
Server:         127.0.0.53
Address:        127.0.0.53#53

** server can't find test.tail: NXDOMAIN

$ nslookup <hostname>.<subdomain>.ts.net
Server:         127.0.0.53
Address:        127.0.0.53#53

Non-authoritative answer:
Name:   <hostname>.<subdomain>.ts.net
Address: <Correct IP>

And what does your AdGuard log show? Does it actually get the DNS request and then does a rewrite?

image upload isn’t working for some reason, so this is the link to an image of the result.
i also get this with dig:

dig <host>.tail @100.100.100.100

; <<>> DiG 9.18.13 <<>> <host>.tail @100.100.100.100
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 664
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;<host>.tail.                      IN      A

;; AUTHORITY SECTION:
ts.net.                 279     IN      SOA     ns1.dnsimple.com. admin.dnsimple.com. 1615468532 86400 7200 604800 300

;; Query time: 8 msec
;; SERVER: 100.100.100.100#53(100.100.100.100) (UDP)
;; WHEN: Thu May 04 20:11:49 CEST 2023
;; MSG SIZE  rcvd: 101

I see you used dig explicitly with the tailnet’s DNS server (100.100.100.100).
Is that definitely the DNS server that your AdGuard service would use when trying to resolve the rewritten *.tail domains?

Otherwise, what I think might be happening is:
It rewrites the request into *.ts.net, but then tries to resolve that with the DNS server(s) it normally uses (instead of passing it to 100.100.100.100).

I would imagine you’d somehow need to tell AdGuard that any requests for *.tail are not only to be rewritten to *.ts.net, but to then also be forwarded to 100.100.100.100.
Otherwise it might try to resolve the *.ts.net with the public DNS servers of Tailscale (on the internet), which will obviously not be able to resolve that to one of your tailnet IPs (except maybe if you’re using funnel).

Not sure if you can do that within the custom rules as well, or if you need to change some settings on the DNS page of AdGuard. I never used it before, so I’m not familiar with it.