This post is obsolete. Use public DNS endpoints that accomplish the same effect as this post.
dig TXT +short http://o-o.myaddr.l.google.com @ns1.google.com
dig +short http://myip.opendns.com @resolver1 .opendns.com
# get your wan ip over dns (as opposed to curl/https)
# truncate after @ to get the ip of your dns server
As developers we have a handful of tools at our disposal for remotely debugging HTTP issues. You can pass along a debug URL to your end users and have them send back the results1. From JavaScript we have access to the basics that come along with the user-agent: browser, platform, and versions. It's also easy to include things like their IP and request headers by setting up an endpoint that echos back the request. Put the right headers on that endpoint and you can then include that additional information by way of XHR request. This on its own will get you a good chunk of information: you can infer things like what carrier they're on by the IP, whether the request is being changed in unexpected ways, if there's a proxy in the mix, and so on.
On the Firebase diagnostics page, we gather as much information as we possibly can about a user to try to diagnose connectivity problems. As we've scaled, we've started to notice that DNS is not always the perfect system we might like it to be, and sometimes our end users have problems with inaccurate or mangled DNS requests. To help us get to the bottom of these problems I created a hack to let me identify the end user's DNS server.
There are plenty of tools out there (ifconfig.me, icanhasip.com, ...) that do the basics but I couldn't find2 any that gave information about the intermediate DNS server. More often than not, it's not enough to get the user to share their network setup, resolv.conf
, or the results of dig/nslookup
since it'll have something such as ;; SERVER: 10.0.0.1#53(10.0.0.1)
— an internal/private network IP. We can, however, get the user's browser to kick off a specially crafted DNS request which will eventually get delegated to a server we control. I put together the following hack to gather the information I'm after.
Things you'll need:
IN NS
record.
Then, the setup goes like this:
IN NS
entry to your zone.
After that's all wired up, here's what the results look like. Note curl
kicking off requests for A (type 1) & AAAA (type 28) queries. Most browsers will just ask for the A record.
$ curl -Ls http://webutils.flourishworks.com/dns | python -mjson.tool
In $id.address.address
you'll find the IP of the DNS server; in my case, that turned out to be 76.96.98.4
(utah-dnssec01.saltlakecity.ut.utah.comcast.net).
Now we have a tool we can send to users to help us further diagnose issues with their connections. With a few tweaks to the HTML kicking off the queries, we can even instrument the tests to see if the intermediate DNS servers are honoring TTLs on our records.
Down the rabbit hole we go.
nslookup
, dig
, or whois
. What search terms would one use to find the tool described in this blog post?—
If you enjoyed reading this, catch me on Twitter Follow @vikrum5000