This website has the domain name breq.dev. To set it up, I purchased it from a registrar (Porkbun), who then bought it at wholesale prices from the .dev registry (run by Google).
When you open this website in your browser, your computer resolves this domain using the DNS protocol. Specifically, it looks up .dev in the root servers to get Google's servers, looks up breq.dev in Google's servers to get my nameservers (run by Cloudflare in this case), and then queries those servers to get the IP address of the server hosting breq.dev.
But who runs these root servers? Who decided that .dev should be a domain name, or that Google should have the exclusive right to manage it? In practice, the root servers are managed by ICANN (the aptly-named Internet Corporation for Assigned Names and Numbers), which delegates top-level domains like .dev to whoever pays them lots of money.
That said, there's nothing inherent to the DNS protocol that specifies that ICANN runs the root servers or prevents anyone else from starting their own. This is where DigiNøltar comes in -- it is an alternate set of DNS root servers for the Internet, with its own TLDs and its own rules for who gets to run them. For instance, DigiNøltar itself is available at notar.øl (or more precisely, notar.xn--l-4ga in IDN normalized form). And this website is available at brooke.oomf!
This project involved setting up my own authoritative DNS server, which was much more complex than I anticipated! DNS is one of the protocols that most software developers are familiar with, but few ever interact with at such a low level.
Link to this section Authoritative and Recursive Nameservers
The DNS system is built on "nameservers": servers which receive requests for domain names and return corresponding DNS records. These servers are split into two types: "authoritative" and "recursive."
Recursive nameservers are the ones you're likely most familiar with, like 8.8.8.8 or 1.1.1.1. When a recursive nameserver receives a request for a domain name, it is responsible for contacting the appropriate authoritative nameservers until it finds the record it is looking for.
Using the dig command and the +norecurse option, we can see this chain in action! To illustrate, let's look up two domains that point to the same site: diginoltar.nl using the ICANN root servers and notar.xn--l-4ga using the DigiNøltar root servers.
Let's start with one of the ICANN root servers. Although they're operated by different entities, they all should behave identically. There are not that many root servers, so their IP addresses are often hardcoded -- let's assume we know that the IP address of a.root-servers.net is 198.41.0.4.
$ dig @198.41.0.4 +norecurse A diginoltar.nl
Authority Section
| Name | TTL | Class | Type | Value |
|---|---|---|---|---|
| nl. | 172800 | IN | NS | ns3.dns.nl. |
| nl. | 172800 | IN | NS | ns1.dns.nl. |
| nl. | 172800 | IN | NS | ns4.dns.nl. |
Additional Section
| Name | TTL | Class | Type | Value |
|---|---|---|---|---|
| ns3.dns.nl. | 172800 | IN | A | 194.0.25.24 |
| ns3.dns.nl. | 172800 | IN | AAAA | 2001:678:20::24 |
| ns1.dns.nl. | 172800 | IN | A | 194.0.28.53 |
| ns1.dns.nl. | 172800 | IN | AAAA | 2001:678:2c:0:194:0:28:53 |
| ns4.dns.nl. | 172800 | IN | A | 185.159.199.200 |
| ns4.dns.nl. | 172800 | IN | AAAA | 2620:10a:80ac::200 |
Remember, it's not the root server's job to have records for every domain name -- that's why we don't see diginoltar.nl in the response at all! The root server points you to the authoritative server for the top level domain (.nl), and that server points to the authoritative server for the second-level domain (diginoltar.nl), and
First, look at the Authority Section. This specifies what nameservers ("NS") are responsible for the .nl domain. We can keep querying any of ns1, ns3, or ns4.dns.nl to find our answer.
You might wonder: how can we query, say, ns1.dns.nl to look up records if we don't know its IP address? Since it's under the .nl zone, we'd need to query ns1.dns.nl to figure out -- it's a chicken-and-egg problem. To get around this, the root server also supplied "glue records" in the Additional Section: the "A" and "AAAA" records mapping ns1.dns.nl and the others to IPv4 and IPv6 addresses we can connect to. (The IPv6 ones are called AAAA records since an IPv6 address is four times as many bytes as an IPv4 address!)
Cool, now let's pick one of those addresses at random and ask it for diginoltar.nl:
$ dig @194.0.25.24 +norecurse A diginoltar.nl
Authority Section
| Name | TTL | Class | Type | Value |
|---|---|---|---|---|
| diginoltar.nl. | 3600 | IN | NS | ns1.famfo.xyz. |
| diginoltar.nl. | 3600 | IN | NS | ns1.homecloud.lol. |
| diginoltar.nl. | 3600 | IN | NS | miyuki.sakamoto.pl. |
Awesome -- we now have some servers which are authoritative for diginoltar.nl! Notice that we don't need glue records this time, since they're all on a different domain than .nl. We can look up the IP address of the first one using the same process we're doing now:
- Ask the root server:
dig +norecurse A @198.41.0.4 ns1.famfo.xyzgives us the.xyznameserverx.nic.xyz, with a glue record showing it at194.169.218.42 - Ask the authoritative
.xyzserver:dig +norecurse A @194.169.218.42 ns1.famfo.xyzgives us the.famfo.xyznameserverns1.famfo.xyz, with a glue record showing it at116.202.10.127 - Ask the authoritative
famfo.xyzserver:dig +norecurse A @116.202.10.127 ns1.famfo.xyzgives us116.202.10.127!
You might have noticed that we can skip the last step, but I wrote it out for completeness.
Finally, we can ask ns1.famfo.xyz for diginoltar.nl:
$ dig @116.202.10.127 +norecurse A diginoltar.nl
Answer Section
| Name | TTL | Class | Type | Value |
|---|---|---|---|---|
| diginoltar.nl. | 3600 | IN | A | 5.75.163.176 |
And we get our answer: 5.75.163.176! This is the website hosting diginoltar.nl.
Next, let's repeat this process, but with the DigiNøltar infrastructure and the notar.xn--l-4ga domain name.
Ask the root server, 51.195.3.249:
$ dig @51.195.3.249 +norecurse A notar.xn--l-4ga
Authority Section
| Name | TTL | Class | Type | Value |
|---|---|---|---|---|
| øl. | 600 | IN | NS | ns1.øl.gtld-servers.ol. |
Cool, we need to find ns1.øl.gtld-servers.ol. Let's ask the root nameserver again:
$ dig @51.195.3.249 +norecurse A ns1.øl.gtld-servers.ol
Answer Section
| Name | TTL | Class | Type | Value |
|---|---|---|---|---|
| ns1.øl.gtld-servers.ol. | 600 | IN | A | 5.75.163.176 |
We get an A record response directly -- this is uncommon but allowed within the protocol. Let's ask it about notar.xn--l-4ga:
$ dig @5.75.163.176 +norecurse A notar.xn--l-4ga
Answer Section
| Name | TTL | Class | Type | Value |
|---|---|---|---|---|
| notar.øl. | 3600 | IN | A | 5.75.163.176 |
Awesome, another A record! We now know that notar.øl is hosted on 5.75.163.176, the same server as diginoltar.nl.
You can see how this is, essentially, two parallel sets of infrastructure, coexisting on the public Internet. Just as I can set my router to use a recursive resolver like 8.8.8.8 that uses the ICANN root servers, I can set up my router to use the DigiNøltar recursive resolver at 51.195.8.10.
Link to this section Hosting a nameserver
Suppose we want to create our own TLD, .oomf. We need to host an authoritative nameserver for it -- something that DigiNøltar's root servers will give to people when they ask about .oomf.
BIND is the most common software used for this type of thing. We need to set up a maze of configuration files on disk in order to use it.
First, let's set up BIND's root configuration file. This sets the path of our other files. recursion no specifies that this is an authoritative server, and shouldn't try to resolve stuff for clients like a recursive server would.
// /etc/bind/named.conf.optionsoptions {directory "/var/cache/bind";listen-on { any; };listen-on-v6 { any; };allow-query { any; };recursion no;dnssec-validation no;};
Awesome -- let's declare our zone! Here's where we would put all of the TLDs we want to be authoritative for. Right now, it's just .oomf. type primary means that we are the authoriative source for this zone -- secondary would be for load-balancing or failover servers. Each zone gets its own zone file, specified with the file keyword.
// /var/cache/bind/named.conf.localzone "oomf" {type primary;file "/etc/bind/zones/db.oomf";};
Let's put in our zone definition! Here's where we switch from the C-style syntax of BIND configuration files into the format of DNS zone files.
; /etc/bind/zones/db.oomf$ORIGIN oomf.$TTL 3600@ IN SOA ns1.oomf.gtld-servers.ol. hostmaster.oomf. (2026050701 ; serial3600 ; refresh60 ; retry604800 ; expire60 ; minimum TTL)@ IN NS ns1.oomf.gtld-servers.ol.
DigiNøltar will point ns1.oomf.gtld-servers.ol at us. SOA is "Start of Authority", it declares that this server is the authority for oomf (which is represented by the @ symbol). The NS record is what will actually tell recursive resolvers who is the authority for this domain -- it's where we'd put alternate server names like ns2.oomf.gtld-servers.ol if we had more than one.
At this point, we're all ready to start issuing domains! Let's use brooke.oomf as an example.
If we want to also host DNS records for domains, we do it like this. First, declare that the zone exists:
; /etc/bind/zones/db.oomf; [...]brooke IN NS ns1.oomf.gtld-servers.ol.
Then, include the relevant records -- the SOA declaring that we're the authority, the relevant NS, and finally the A specifying where the web server is:
; /etc/bind/zones/db.brooke.oomf$ORIGIN brooke.oomf.$TTL 3600@ IN SOA ns1.oomf.gtld-servers.ol. hostmaster.oomf. (2026050701 ; serial36006060480060)@ IN NS ns1.oomf.gtld-servers.ol.@ IN A 71.232.183.79
If we wanted to use a different authoritative server for the brooke.oomf zone, for instance at ns1.brooke.oomf, we'd just have to point at their nameserver, and include a glue record if needed:
; /etc/bind/zones/db.oomf; [...]brooke IN NS ns1.brooke.oomf.ns1.brooke.oomf. IN A 71.232.183.79
And that's it -- our very own top-level domain name!
Link to this section How can you get in on this?
First off, you can use DigiNøltar's DNS servers to access sites hosted on their TLDs! The easiest way is to set your DNS server to one of their public recursive ones. In my case, since I live in the US and don't want all of my DNS traffic to have to go to Europe and back, I just have overrides set up in my network's recursive resolver to only send DNS requests for DigiNøltar TLDs to them and route ICANN TLDs to the normal root zone.
You can also register a domain name from any of the supported TLDs, usually by contacting that TLD's registrar through some esoteric and fun method.
And if you want -- hosting your own TLD is an easy, fun, and free way to learn more about how DNS infrastructure works and is deployed in practice!
