In the vast landscape of the Linux operating system, one fundamental process silently operates behind the scenes, playing a crucial role in connecting you to the digital world—the Domain Name System (DNS) resolution. This blog post aims to demystify the intricacies of DNS resolution in Linux, shedding light on the steps your system takes to convert user-friendly domain names into machine-readable IP addresses.

Table of Contents
Understanding the Basics of DNS resolution
DNS resolution is the process by which a domain name, such as http://www.gulian.uk, is translated into its corresponding IP address, like 192.0.78.136.
petru@ubuntu-dev:~$ dig gulian.uk
; <<>> DiG 9.18.12-0ubuntu0.22.04.3-Ubuntu <<>> gulian.uk
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26190
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;gulian.uk. IN A
;; ANSWER SECTION:
gulian.uk. 249 IN A 192.0.78.136
gulian.uk. 249 IN A 192.0.78.228
;; Query time: 187 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Mon Oct 02 19:48:00 BST 2023
;; MSG SIZE rcvd: 70
petru@ubuntu-dev:~$ ^C

Linux, being a versatile and open-source platform, employs a series of steps to accomplish this task seamlessly.
/etc/resolv.conf:
At the heart of DNS configuration in Linux lies the /etc/resolv.conf
file. This file contains information about the DNS servers that your system should query when resolving domain names. Users can manually change/configure this file to specify preferred DNS servers.
Resolv.conf manual page:
RESOLV.CONF(5) Linux Programmer's Manual RESOLV.CONF(5)
NAME
resolv.conf - resolver configuration file
SYNOPSIS
/etc/resolv.conf
DESCRIPTION
The resolver is a set of routines in the C library that provide access
to the Internet Domain Name System (DNS). The resolver configuration
file contains information that is read by the resolver routines the
first time they are invoked by a process. The file is designed to be
human readable and contains a list of keywords with values that provide
various types of resolver information. The configuration file is con‐
sidered a trusted source of DNS information; see the trust-ad option
below for details.
If this file does not exist, only the name server on the local machine
will be queried, and the search list contains the local domain name de‐
termined from the hostname.

Name Service Switch (NSS):
The Name Service Switch is a crucial library that facilitates communication between programs and system databases, including DNS. It determines the order in which different sources are queried for information. In the context of DNS resolution, it often includes “dns” in the hosts entry of the /etc/nsswitch.conf
file.
nsswitch.conf manual page:
NSSWITCH.CONF(5) Linux Programmer's Manual NSSWITCH.CONF(5)
NAME
nsswitch.conf - Name Service Switch configuration file
DESCRIPTION
The Name Service Switch (NSS) configuration file, /etc/nsswitch.conf,
is used by the GNU C Library and certain other applications to deter‐
mine the sources from which to obtain name-service information in a
range of categories, and in what order. Each category of information
is identified by a database name.
The file is plain ASCII text, with columns separated by spaces or tab
characters. The first column specifies the database name. The remain‐
ing columns describe the order of sources to query and a limited set of
actions that can be performed by lookup result.
The following databases are understood by the GNU C Library:
aliases Mail aliases, used by getaliasent(3) and related functions.
ethers Ethernet numbers.
group Groups of users, used by getgrent(3) and related functions.
hosts Host names and numbers, used by gethostbyname(3) and related functions.

nsswitch.conf manual page
The Resolution Journey
Now, let’s dive into the steps your Linux system takes when resolving a domain name.
User Request:
It all begins with a user or a program making a request to access a website or server using its domain name (e.g., http://www.gulian.uk).
NSS and glibc Functions:
The request triggers the Name Service Switch and the C library’s functions, such as gethostbyname
. These functions initiate the DNS resolution process.
nsswitch.conf Configuration:
The nsswitch.conf
file comes into play, defining the order in which various sources are consulted for resolution. For DNS, it typically includes “dns” in the hosts entry. On my Linux host, the first source is the file /etc/hosts and the last option is the DNS server.
petru@ubuntu-dev:~$ grep hosts /etc/nsswitch.conf
hosts: files mdns4_minimal [NOTFOUND=return] dns
petru@ubuntu-dev:~$

Local Cache:
Linux systems often employ a local DNS cache, such as systemd-resolved
or dnsmasq
. If the requested domain was recently resolved, its information might be present in the cache, speeding up the process.
/etc/hosts:
Before reaching out to DNS servers, the system checks the local /etc/hosts
file. This file contains manual mappings of hostnames to IP addresses, providing a quick lookup option.
petru@ubuntu-dev:~$ cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 ubuntu-dev
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
# Manual mapping entry added by Petru
#
10.10.10.10 server.gulian.uk
petru@ubuntu-dev:~$

DNS Query:
If the local cache and /etc/hosts
file do not yield results, the system sends a DNS query to the specified DNS servers in /etc/resolv.conf
. These servers then respond with the corresponding IP address for the requested domain.
petru@ubuntu-dev:~$ cat /etc/resolv.conf
# This is /run/systemd/resolve/stub-resolv.conf managed by man:systemd-resolved(8).
# Do not edit.
#
# This file might be symlinked as /etc/resolv.conf. If you're looking at
# /etc/resolv.conf and seeing this text, you have followed the symlink.
#
# This is a dynamic resolv.conf file for connecting local clients to the
# internal DNS stub resolver of systemd-resolved. This file lists all
# configured search domains.
#
# Run "resolvectl status" to see details about the uplink DNS servers
# currently in use.
#
# Third party programs should typically not access this file directly, but only
# through the symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a
# different way, replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.
nameserver 127.0.0.53
options edns0 trust-ad
search broadband
petru@ubuntu-dev:~$

Below I performed 2 queries. For the first query, the response came from /etc/hosts file.
For the second query, the response was provided by the name server 127.0.0.53.
petru@ubuntu-dev:~$ nslookup server.gulian.uk
Server: 127.0.0.53
Address: 127.0.0.53#53
Name: server.gulian.uk
Address: 10.10.10.10
petru@ubuntu-dev:~$ nslookup gulian.uk
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: gulian.uk
Address: 192.0.78.228
Name: gulian.uk
Address: 192.0.78.136

Host utility used for DNS resolution
Linux provides multiple utilities that you can use for DNS resolution.
Let’s start with the host utility.
Host man page.
HOST(1) BIND 9 HOST(1)
NAME
host - DNS lookup utility
SYNOPSIS
host [-aACdlnrsTUwv] [-c class] [-N ndots] [-p port] [-R number] [-t type] [-W wait] [-m flag] [
[-4] | [-6] ] [-v] [-V] {name} [server]
DESCRIPTION
host is a simple utility for performing DNS lookups. It is normally used to convert names to IP
addresses and vice versa. When no arguments or options are given, host prints a short summary of
its command-line arguments and options.
name is the domain name that is to be looked up. It can also be a dotted-decimal IPv4 address or
a colon-delimited IPv6 address, in which case host by default performs a reverse lookup for that
address. server is an optional argument which is either the name or IP address of the name
server that host should query instead of the server or servers listed in /etc/resolv.conf.
OPTIONS
-4 This option specifies that only IPv4 should be used for query transport. See also the -6
option.
-6 This option specifies that only IPv6 should be used for query transport. See also the -4
option.

Examples of DNS resolution using the host utility.
petru@ubuntu-dev:~$ host google.com
google.com has address 142.250.187.238
google.com has IPv6 address 2a00:1450:4009:815::200e
google.com mail is handled by 10 smtp.google.com.
petru@ubuntu-dev:~$

Specify a different DNS server for DNS resolution.
petru@ubuntu-dev:~$ host cisco.com 8.8.8.8
Using domain server:
Name: 8.8.8.8
Address: 8.8.8.8#53
Aliases:
cisco.com has address 72.163.4.185
cisco.com has IPv6 address 2001:420:1101:1::185
cisco.com mail is handled by 30 aer-mx-01.cisco.com.
cisco.com mail is handled by 10 alln-mx-01.cisco.com.
cisco.com mail is handled by 20 rcdn-mx-01.cisco.com.
petru@ubuntu-dev:~$

Specify a different record type for DNS resolution.
petru@ubuntu-dev:~$ host -t NS gulian.uk
gulian.uk name server ns1.wordpress.com.
gulian.uk name server ns2.wordpress.com.
gulian.uk name server ns3.wordpress.com.
petru@ubuntu-dev:~$

Nslookup utility used for DNS resolution
Another utility that you can use for DNS resolution is nslookup. This utility is also present on the Windows operating system.
nslookup man page.
NSLOOKUP(1) BIND 9 NSLOOKUP(1)
NAME
nslookup - query Internet name servers interactively
SYNOPSIS
nslookup [-option] [name | -] [server]
DESCRIPTION
nslookup is a program to query Internet domain name servers. nslookup
has two modes: interactive and non-interactive. Interactive mode allows
the user to query name servers for information about various hosts and
domains or to print a list of hosts in a domain. Non-interactive mode
prints just the name and requested information for a host or domain.
ARGUMENTS
Interactive mode is entered in the following cases:
a. when no arguments are given (the default name server is used);
b. when the first argument is a hyphen (-) and the second argument is
the host name or Internet address of a name server.

With nslookup you can perform DNS resolution in interactive mode or non-interactive mode.
Example of DNS resolution in interactive mode:
petru@ubuntu-dev:~$ nslookup
> gulian.uk
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: gulian.uk
Address: 192.0.78.228
Name: gulian.uk
Address: 192.0.78.136
> cisco.com
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: cisco.com
Address: 72.163.4.185
Name: cisco.com
Address: 2001:420:1101:1::185
>
[1]+ Stopped nslookup
petru@ubuntu-dev:~$

Example of DNS resolution in non-interactive mode:
petru@ubuntu-dev:~$ nslookup gulian.uk
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: gulian.uk
Address: 192.0.78.228
Name: gulian.uk
Address: 192.0.78.136
petru@ubuntu-dev:~$ nslookup gulian.uk 1.1.1.1
Server: 1.1.1.1
Address: 1.1.1.1#53
Non-authoritative answer:
Name: gulian.uk
Address: 192.0.78.228
Name: gulian.uk
Address: 192.0.78.136
petru@ubuntu-dev:~$

To perform DNS resolution for a different record type use the -querytype option.
petru@ubuntu-dev:~$ nslookup -querytype=AAAA cisco.com
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: cisco.com
Address: 2001:420:1101:1::185
petru@ubuntu-dev:~$

Dig utility used for DNS resolution
The third utility that you can use for DNS resolution is dig. This is my preferred tool for performing DNS resolutions.
Dig man page.
DIG(1) BIND 9 DIG(1)
NAME
dig - DNS lookup utility
SYNOPSIS
dig [@server] [-b address] [-c class] [-f filename] [-k filename] [-m]
[-p port#] [-q name] [-t type] [-v] [-x addr] [-y [hmac:]name:key] [
[-4] | [-6] ] [name] [type] [class] [queryopt...]
dig [-h]
dig [global-queryopt...] [query...]
DESCRIPTION
dig is a flexible tool for interrogating DNS name servers. It performs
DNS lookups and displays the answers that are returned from the name
server(s) that were queried. Most DNS administrators use dig to trou‐
bleshoot DNS problems because of its flexibility, ease of use, and
clarity of output. Other lookup tools tend to have less functionality
than dig.

Simple lookup with dig utility:
petru@ubuntu-dev:~$ dig gulian.uk
; <<>> DiG 9.18.12-0ubuntu0.22.04.3-Ubuntu <<>> gulian.uk
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 588
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;gulian.uk. IN A
;; ANSWER SECTION:
gulian.uk. 124 IN A 192.0.78.228
gulian.uk. 124 IN A 192.0.78.136
;; Query time: 3 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Mon Oct 02 21:01:54 BST 2023
;; MSG SIZE rcvd: 70

To specify a different DNS server when performing DNS resolution, run the below command.
petru@ubuntu-dev:~$ dig gulian.uk @208.67.222.222
; <<>> DiG 9.18.12-0ubuntu0.22.04.3-Ubuntu <<>> gulian.uk @208.67.222.222
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59334
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;gulian.uk. IN A
;; ANSWER SECTION:
gulian.uk. 300 IN A 192.0.78.136
gulian.uk. 300 IN A 192.0.78.228
;; Query time: 15 msec
;; SERVER: 208.67.222.222#53(208.67.222.222) (UDP)
;; WHEN: Mon Oct 02 21:04:40 BST 2023
;; MSG SIZE rcvd: 70
petru@ubuntu-dev:~$

In order to check for different record types when performing lookups, run a similar command.
petru@ubuntu-dev:~$ dig cisco.com AAAA
; <<>> DiG 9.18.12-0ubuntu0.22.04.3-Ubuntu <<>> cisco.com AAAA
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26664
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;cisco.com. IN AAAA
;; ANSWER SECTION:
cisco.com. 730 IN AAAA 2001:420:1101:1::185
;; Query time: 188 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Mon Oct 02 21:05:58 BST 2023
;; MSG SIZE rcvd: 66
petru@ubuntu-dev:~$

Display only the ip address with the +short option.
petru@ubuntu-dev:~$ dig gulian.uk +short
192.0.78.228
192.0.78.136
petru@ubuntu-dev:~$

To make iterative queries with dig, add the +trace option.
petru@ubuntu-dev:~$ dig gulian.uk +trace
; <<>> DiG 9.18.12-0ubuntu0.22.04.3-Ubuntu <<>> gulian.uk +trace
;; global options: +cmd
. 7120 IN NS i.root-servers.net.
. 7120 IN NS c.root-servers.net.
. 7120 IN NS h.root-servers.net.
. 7120 IN NS f.root-servers.net.
. 7120 IN NS g.root-servers.net.
. 7120 IN NS k.root-servers.net.
. 7120 IN NS a.root-servers.net.
. 7120 IN NS m.root-servers.net.
. 7120 IN NS b.root-servers.net.
. 7120 IN NS l.root-servers.net.
. 7120 IN NS j.root-servers.net.
. 7120 IN NS d.root-servers.net.
. 7120 IN NS e.root-servers.net.
;; Received 239 bytes from 127.0.0.53#53(127.0.0.53) in 0 ms
;; UDP setup with 2001:500:2f::f#53(2001:500:2f::f) for gulian.uk failed: network unreachable.
;; UDP setup with 2001:500:2f::f#53(2001:500:2f::f) for gulian.uk failed: network unreachable.
;; UDP setup with 2001:500:2f::f#53(2001:500:2f::f) for gulian.uk failed: network unreachable.
;; UDP setup with 2001:500:2::c#53(2001:500:2::c) for gulian.uk failed: network unreachable.
;; UDP setup with 2001:7fd::1#53(2001:7fd::1) for gulian.uk failed: network unreachable.
;; UDP setup with 2001:dc3::35#53(2001:dc3::35) for gulian.uk failed: network unreachable.
uk. 172800 IN NS nsa.nic.uk.
uk. 172800 IN NS nsb.nic.uk.
uk. 172800 IN NS nsc.nic.uk.
uk. 172800 IN NS nsd.nic.uk.
uk. 172800 IN NS dns1.nic.uk.
uk. 172800 IN NS dns2.nic.uk.
uk. 172800 IN NS dns3.nic.uk.
uk. 172800 IN NS dns4.nic.uk.
uk. 86400 IN DS 43876 8 2 A107ED2AC1BD14D924173BC7E827A1153582072394F9272BA37E2353 BC659603
uk. 86400 IN RRSIG DS 8 1 86400 20231015170000 20231002160000 46780 . UEDqgSMo/3ynu08xdcdGiX8gSvjU101a73OTCic7DORHztrAEVQ4wtOe 49NHywbqRjHFbY9ODtif3LwzeKcRpYu0dXQtZ8HfIcz5X0SLge0XkiQg AnazDqjLTr4kSYJlANU62A8sh657QutuNK7ceHeSu+X8i8R7hX/8Oq92 sHaDVcpP2DEXimJN5/g8Ey4zoEt12kWJZ0oEGZ6kCoglc8OQikL6FAIm L7DTQtbWdbkoBg4uqUMf8dW6NcqmMkqyaGhs7u+YJ+5kwAw9K8VgVcBJ OB9AJj1SMkDlmltdny8yuVxsgTiDv1cSo943aj+y3969JVR5yi79sGV1 v4pFMg==
;; Received 877 bytes from 199.7.83.42#53(l.root-servers.net) in 60 ms
gulian.uk. 172800 IN NS ns1.wordpress.com.
gulian.uk. 172800 IN NS ns2.wordpress.com.
gulian.uk. 172800 IN NS ns3.wordpress.com.
u1fmklfv3rdcnamdc64sekgcdp05bbiu.uk. 10800 IN NSEC3 1 1 0 - U1G6AVNC37MT4HAJ92ES0KP81JT1ILJN NS SOA RRSIG DNSKEY NSEC3PARAM TYPE65534
u1fmklfv3rdcnamdc64sekgcdp05bbiu.uk. 10800 IN RRSIG NSEC3 8 2 10800 20231016023837 20231002014838 43056 uk. X04ZPHra3/TsX6YJ65tZUbKmW+WmRttrx1q+XhV05O4TVy1hCCqVCZ7/ lDRcvJt+A8CFgUta0zHoYmpmRLtHmPa2PiXtHUdyhybmbQ3PE0ALcoHy jJ8SUk+Iye1jvDpjcUb8LRzwvy5uxyIZizbCaGkRe7nfr6PJ9T4Nmw6y +7A=
fji9vfhtfc5kvdnsgg51a61e71m4u9pj.uk. 10800 IN NSEC3 1 1 0 - FJJQVLEISGQHHQ5QOAFC8FGOBQ6J0NK2 NS DS RRSIG
fji9vfhtfc5kvdnsgg51a61e71m4u9pj.uk. 10800 IN RRSIG NSEC3 8 2 10800 20231016083312 20231002074618 43056 uk. 0J1qs/+UK3fEtaHA5Tyn0wtJEysIBh700G12mJphKe9b7+XAua8TGAZX ouCMOVuEel5n6R3qsZX1SFeH9/GpfWcBj1f5rdvbdNkSCxmdnw/V2Nvp 00fx6D6W/B7W21ZIE25a3W1nbUhxsE0F7UGHnuH6nqN41rd270FWfC4/ 010=
;; Received 622 bytes from 103.49.80.1#53(dns2.nic.uk) in 48 ms
gulian.uk. 300 IN A 192.0.78.136
gulian.uk. 300 IN A 192.0.78.228
;; Received 70 bytes from 198.181.116.9#53(ns1.wordpress.com) in 12 ms
petru@ubuntu-dev:~$

Conclusion
DNS resolution is a silent hero in the world of Linux, ensuring that you can effortlessly access your favorite websites without worrying about complex IP addresses. By understanding the underlying process and the key configuration files involved, users can gain insights into how their Linux systems navigate the vast web of interconnected servers. So, the next time you type a URL in your browser, remember the intricate dance of DNS resolution happening behind the scenes, making your digital experiences seamless and efficient.
If you found this blog post helpful, please like and subscribe for more Linux tutorials. Thank you for reading it!