← All articles
Date Published: May, 2026

Doing DNS

Objective : In this we are going to create a dns server and connect all the other machines to this dns server and explore related things.

Before proceeding, create another virtual machine to setup DNS and add it to our private network.

Table Of Contents

  1. What is DNS?
  2. How DNS works?
  3. Example of a full DNS query
  4. Some terminologies related to DNS
  5. Seeing under the hood
  6. Setting up DNS using bind9
  7. Connecting other machines to DNS
  8. Conclusion

What is DNS?

Many people like to describe DNS as the phonebook of the internet. All the machines are assigned IP addresses on the internet. It is not likely to rememeber ip addresses of our favourite websites and other serivces.

When you type a website name like example.com into your browser, computers don't actually use that name to find the site. They ask the DNS server that "Hey! What is the IP of this address" to which DNS replies "Yeah, its 172.66.147.243"

The browser uses this IP address to communicate with the web server and display the website.

How DNS works?

When you try to access an url for example google.com, your browser ( or any other utility ) checks its cache ( or systemd-resolver ) whether does it have this already cached or not.

If not foud, then the recursive DNS resolver ( usually your ISP or a public DNS service ) is queried. This resolver asks a Root DNS server where can I find ".com"?

The Root DNS server are servers which contains information about TLD (Top-Level Domain) for eg .com, .net, .org etc. The IPs of these servers are stored locally on your machine as they are rarely changed.

Now if they are static ips then arent they suseptible to DDOS attacks? Well no, because these are not physical machines. Rather these IPs are hosted using anycast. Where instead of one machine having this particular IP ( which usually happens, one machine one ip ), many machine ( usually in data centers ) host an instance of these servers. So instead of one machine, we have multiple machines in this world serving this IP.

Now, the TLD replies with the authoritative name server ( described below in terminologies ) for google.com. Then the resolver asks the authoritative name server the ip of google.com and the server returns the IP.

The resolver caches the result and returns it to your device. The server can also define a time to live (TTL) for this dns query so that after a certain time, our machine would need to put another request for the same address.

( If this doesn't makes much sense, the following example would clear things up! )

Example of a full DNS query

We will use dig utility to trace the whole journey of our DNS request. This command would return the detailed dns query.

text

                $ dig -4 +trace google.com @8.8.8.8
Dig output
Dig output.

We can observe that it first queries the root DNS server. ( By default, port 53 is used for DNS )

text

                .                       87203   IN  NS  a.root-servers.net.
                .                       87203   IN  NS  b.root-servers.net.
                .                       87203   IN  NS  c.root-servers.net.
                ...
                .                       87203   IN  NS  m.root-servers.net.

                ;; Received 525 bytes from 8.8.8.8#53(8.8.8.8) in 11 ms

One of these server replies with the address of ".com"

text

                com.                    172800  IN  NS  a.gtld-servers.net.
                com.                    172800  IN  NS  b.gtld-servers.net.
                com.                    172800  IN  NS  c.gtld-servers.net.
                ...
                com.                    172800  IN  NS  m.gtld-servers.net.

                ;; Received 1170 bytes from 170.247.170.2#53(b.root-servers.net) in 109 ms

Then one of the ".com" server replies with the address of the authoritative server of google.com

text

                ;; Received 1170 bytes from 170.247.170.2#53(b.root-servers.net) in 109 ms

                google.com.             172800  IN  NS  ns1.google.com.
                google.com.             172800  IN  NS  ns2.google.com.
                google.com.             172800  IN  NS  ns3.google.com.
                google.com.             172800  IN  NS  ns4.google.com.

                ;; Received 644 bytes from 192.12.94.30#53(e.gtld-servers.net) in 238 ms

Then one of the servers from the list replies with ip address of google.com

text

                google.com.             300     IN  A   142.250.77.46

                ;; Received 55 bytes from 216.239.34.10#53(ns2.google.com) in 11 ms

Now this is what exactly happens behind the scenes when your dns resolver tries to resolve the ip address of a url.

Some terminologies related to DNS

  1. Namespace: It is a hierarchial naming structure used to organize domain names on the internet. It starts at the root and branches into top-level domains and then individual domains. Heres how the current structure looks like :
  2. text
    
                                        . (Root )
                                        |
                        -------------------------------------
                        |           |           |           |
                        .com        .org        .edu        .in  <- Top-Level Domains (TLDs)
                        |                                   |
                    example.com                             ac.in 
                        |                                   |
                    -----------                         ----------  
                    |         |                         |        |
                    www      mail                      co.in    gov.in 
                                |                       |        |
                    Host A   Mail Server              college.ac.in
    
    text
    
                    .
                    |__ in
                         |__ ac
                              |__ college 
                                   |__ www.college.ac.in 
                                   |__ mail.college.ac.in 
                                   |__ cs.college.ac.in 
    
  3. Domain: A named section within the namespace. For eg above, college is a domain, mail.college.ac.in is a domain, so on and so forth.
  4. Zone: A portion of the DNS namespace that is managed by a specific administrator or DNS server. A zone contains DNS records for one or more domains or subdomains. For eg college is a zone which contains records for webpage, department info, mail server etc.
  5. Authoritative DNS Server: A DNS server that stores the official DNS records for a zone and provides the final, authoritative answers to DNS queries about names in that zone.

A useful analogy. Imagine the namespace as the world map, it knows where everything is. Domains can be thought of as countries. Zones can be thought of as states in the country. And the Authoritative Server can be thought of as the state government which manages and stores all the records of the state. The zone is just a map, authoritative server is the one which servers.

Seeing under the hood

Before we dive deep, I present to you a summary of how DNS

text

                                   Application
                                (curl, ping, ssh)
                                        │
                                        ▼
                                glibc getaddrinfo()
                                        │
                                        ▼
                                /etc/nsswitch.conf
                                        │
                            ┌─────────────┴─────────────┐
                            ▼                           ▼
                        /etc/hosts                 DNS lookup
                                                        │
                                                        ▼
                                            /etc/resolv.conf
                                            nameserver 127.0.0.53
                                                        │
                                                        ▼
                                        systemd-resolved (local stub)
                                            127.0.0.53:53
                                                        │
                                    ┌────────────────────┼────────────────────┐
                                    ▼                    ▼                    ▼
                                Cache          Interface-specific DNS     DNSSEC/DoT
                                                        │
                                                        ▼
                                        Upstream DNS server (e.g. router,
                                        public DNS, VPN-provided DNS)
                                                        │
                                                        ▼
                                                Authoritative DNS
                                                        │
                                                        ▼
                                                IP address returned
                                                        │
                                                        ▼
                                                    Application connects

Let us say that we use curl to see an webpage. Curl does not implement a mechanism for dns of its own, rather it utilises the existing machinery provided by linux kernel.

Curl calls getaddrinfo() ( provided by glibc ) which reads configuration from /etc/nsswitch.conf . This tells us whether to check /etc/hosts or maybe multicast dns or ask systemd-resolved or use normal dns.

Before DNS lookup happens, this file, /etc/hostsb is checked. If the hostname exists here, no dns query happens. If not then dns query happens.

This file, /etc/resolve.conf contains details of the nameserver to refer to for making the dns query. We would often see 127.0.0.53 being a part of this file. This 127.0.0.53 is the local resolver which forwards our request to systemd-resolved, used by many distributions, it decides where our queries go. This service usually runs on port 53 of 127.0.0.53 as both TCP and UDP port. So finally, applications send their packets to 127.0.0.53:53

The systemd-resolved is required because it provides DNS cache, VPN support, DNS over TLS, Better integration with network managers, Per-interface DNS, DNSSEC validation etc. To interact with systemd-resolved we can use resolvectl

The systemd-resolved is the daemon itself which receives dns request, caches them, chooses dns server and forwards query. It gets its DNS servers usually from DHCP, static configuration, NetworkManager, systemd-networkd, VPN etc.

Also /etc/resolv.conf can be asymlink which means /etc/resolve.conf -> /run/systemd/resolve/stud-resolve.conf which contains "nameserver 127.0.0.53". It is diff from /resolve.conf as /etc/resolve.conf contains the actual upstream DNS server.

So in summary, /etc/resolv.conf tells applications where to send DNS queries, while systemd-resolved determines how and where those queries are ultimately resolved, adding caching and other functionalities.

Setting up DNS using bind9

First of all we install:
text

                $ sudo apt install bind9 bind9utils dnsutils

Bind9 is the DNS server, bind9-utils contains the management tools and dnsutils contains tools like dig.

Now we study the configuration files. The typical layout is something like this:

text

                /etc/bind/

                named.conf ( simply loads the below mentioned files ) 
                named.conf.options ( options for the dns server )
                named.conf.local (local zones )
                named.conf.default-zones ( default zones )

                /etc/bind/zones 

To creat our own zone we edit the /etc/bind/named.conf.local file.

vim

                zone "lab.local" {
                    type master;
                    file "/etc/bind/zones/db.lab.local";
                }

Here, the map or the information would be in the zones folder in the db.lab.local file. Now we create the zone file ( do it yourself ).

vim

                $TTL 604800
                @    IN SOA dns1.lab.local admin.lab.local (
                         2
                         604800
                         86400
                         2419200
                         604800 )    
                @        IN NS dns1.lab.lcoal. 
                dns1   IN A 10.2.0.20
                server IN A 10.2.0.10
                web    IN A 10.2.0.30

The TTL specifies for how long we should cache the dns query before asking for it again. Other parameters inside the bracket can be understood by reading the docs.

SOA means start of authority which contains metadata. NS means nameserver so lab.local would have dns1.lab.local as its nameserver. And obviously at the end we add our records so for eg web.lab.local would correspond to 10.2.0.30.

Now we just restart bind9 and check if the files work.

text

                $ sudo named-checkconf
                $ sudo named-checkzone lab.local /etc/bind/zones/db.lab.local 
                $ sudo systemctl restart bind9 

And now we have our dns server. We can test it using

text

                $ dig @127.0.0.1 web.lab.local

Connecting other machines to DNS

To allow other machines to connect, we simply configure the netplan file.

text

                network:
                    ethernet:
                        enp0s8:
                            addresses:
                                - 10.2.0.20/24
                            nameservers:
                                addresses:
                                    - 10.2.0.20
                                search:
                                    - lab.local
                            dhcp4: false
                            dhcp6: false
                    version: 2

In this we added the nameservers where we mentioned the address of our dns server in our local network and also included the lab.local doamin which basically means that when any query related to this domain floats, send it to enp0s8. Another way if you are not using bind9 then you can manually add the nameserver in /etc/resolve.conf .

Conclusion

In this article we set up a DNS server and connect other machines to this DNS server. Also we explored some other tools and understood how DNS works.