Fuzzy DNS

For some reason, I thought it might be a good idea to tolerate typos in subdomain names. I added this idea to my Google keep’s idea pool, left it there and forgot about it. I searched for already built DNS servers in Go to fork and extend but I didn’t find one. So the main reason it stayed in the idea pool for that long, was the burden of implementing a DNS server. Until I stumbled upon this yesterday. I read the code and found that it’s not that hard to implement a minimal DNS server. So out of boredom, I finally took it out of the idea pool and fuzzy-dns was born. The README file describes the technical details.

The main reason I’m writing this post is the “Today I Learned” part. The first challenge was, how I am going to store the records configuration of the server. First thought was a Zone File. The dns package has a parser for zone files so it seemed like a good idea. I read its wikipedia page, but I found that it would be complicated for users to maintain. So I decided to go with a simple YAML array in the server’s config file.

I knew about the DNS record types (A, AAAA, CNAME, …). I used them to configure my own domains, but I’ve never built a DNS server before. I don’t know how the records are served. This was the second challenge. One question I had was “how are CNAME records served?”. Browsers, for instance, query only for the A record. So I started wireshark, filtered for DNS packets and started capturing. I found that although an A record is requested, sometimes CNAME records are returned. I started a terminal and decided to test it myself on my own subdomains to understand.

$ dig +noall +answer A blog.mbassem.com

blog.mbassem.com.       1799    IN      CNAME   mohamedbassem.github.io.
mohamedbassem.github.io. 3599   IN      CNAME   github.map.fastly.net.
github.map.fastly.net.  7       IN      A

Although I’m asking for an A record. I got some CNAME records in the response. After some digging in RFC 1034 I found:

“CNAME RRs cause special action in DNS software. When a name server fails to find a desired RR in the resource set associated with the domain name, it checks to see if the resource set consists of a CNAME record with a matching class. If so, the name server includes the CNAME record in the response and restarts the query at the domain name specified in the data field of the CNAME record. The one exception to this rule is that queries which match the CNAME type are not restarted.”

That’s how the first question was answered. The second question was what if there are a CNAME and an A records for the same subdomain? The answer was in the wiki page of CNAME records.

An alias defined in a CNAME record must have no other resource records of other types (MX, A, etc.).

Those were the two main questions I had. I implemented the server, deployed it to a DigitalOcean droplet, changed my GoDadday’s DNS records to give it a try and it worked.

Is it useful? I don’t know. I just thought that it’s an experiment that’s worth trying.

If you have any other ideas, comments or questions, please share them with me in the comments.