DNS - Resource records, DNS tools, DNSSec (Part 2)

DNS - Resource records, DNS tools, DNSSec (Part 2)
Photo by Belinda Fewings / Unsplash

In the last article, I said that the DNS zone is defined for each domain and that it’s a file that consists of Resource Records. When the DNS resolver forwards the domain name to the DNS server, it gets the resource records that match that domain from it.

DNS  zone can include a single domain name, one domain, many subdomains, or many domain names. Usually, the DNS zone is equivalent to 'domain’, but it doesn’t have to be.

Resource Records

Resource Record is comprised of 5 fields:

  • Name - it can be a domain name or host address
  • Time to live (TTL) - how long the record will “live” in those caches I mentioned in the last article. It shows how stable the record is. The bigger this number is, the longer the record will be kept in the cache. For ex. SOA record which we will examine shortly this value is 86400 which is 24h (TTL values are in seconds).
  • Class - for data that is important for the Internet, this is always IN, for other, non-Internet data other codes can be used, but very rarely.
  • Type  - type of record. You can see the most important types in the table below.
  • Value - the value that is assigned to the RR (ex. address, name, etc.)

SOA (Start of Authority)

This is the first record in each DNS zone.
SOA record contains the name of the primary DNS server, email of the DNS administrator (optional, and nowadays mostly skipped due to spam issues), unique serial number, and various other indicators and timers.

$ORIGIN vps-playground.cloud.
$TTL 86400
; SOA Records
@		IN	SOA	hydrogen.ns.hetzner.com. dns.hetzner.com. 2023011205 86400 10800 3600000 3600

Serial number (version, in the example above 2023011205) for DNS zone file - this “number” is in format “yyyymmddnn” and it has to be incremented during every change so that secondary DNS knows and it can retrieve it. This was a common mistake when handling DNS zone files, not having the serial number incremented, and thus not propagating changes to secondary DNS servers. However, by using any of the VPS provider’s dashboards for updating DNS zone files, this value is incremented automatically, after you make any changes to the DNS zone file.

This process of sending a DNS record from a primary DNS server to a secondary is called a zone transfer. In the Part 1 I said that DNS data is sent over port UDP port 53, this zone transfer is an exception, and it’s sent over TCP (because we need to ensure the transfer was completed correctly, hence the more reliable protocol).

Refresh timer - after how many seconds secondary DNS will check for changes on the primary
Retry - if the check didn’t succeed, after how many seconds the retry will happen
Expire - How long DNS zone(s) from primary will be kept
Minimum  - sets the time to live for negative answers that are cached*

*From the example above you can see $TTL directive defines times for all records in the zone file. This is the default value for positive answers (i.e., actual records). The minimum parameter in the SOA record sets the time to live for negative answers that are cached (cache misses if you will).

NS records

NS (name server) records identify the authoritative servers for a zone.
These records are usually defined, just after the SOA record. The format is:

zone [ttl] [IN] NS hostname

; NS Records, "@" - represents root
@	600	IN	NS	helium.ns.hetzner.de.
@	600	IN	NS	hydrogen.ns.hetzner.com.
@	600	IN	NS	oxygen.ns.hetzner.com.
NS records

A record (IPv4 address)

This is the key record of the DNS database, because they provide ma mapping from hostname to IP address. The format is:

hostname [ttl] [IN] A ipaddr

www	300	IN	A	142.132.165.72
example of A record

AAAA record (IPv6 address)

IPv6 equivalent of A records. IPv6 records in your DNS zone don’t mean you have to answer DNS queries over IPv6. The format is:

hostname [ttl] [IN] AAAA ipaddr

f.root-servers.net. IN AAAA 2001:500:2f::f
example of AAAA record

MX

MX records are used by mail systems to route emails more efficiently. MX records specify the host's name prepared to accept the email for the specified domain.

The format of an MX record is: name [ttl] [IN] MX preference host ...

mail.vps-playground.cloud  86400 IN MX 10 mail
example of MX record

The preference or priority parameter is indicating which host has a priority for receiving/handling emails. In case of message send failure, the server will default to host with next priority preference (lower number means bigger priority).

example.com record type priority value TTL
@ MX 10 mailserver1.exmaple.com 45000
@ MX 20 mailserver2.example.com 45000

When a user sends an email, the MTA (Mail Transfer Agent), sends a DNS query to identify the mail servers for the email recipients. SMTP connection will be established with the domain with the highest priority (mailserver1 in the example above).

CNAME record

This record allows aliases to be created. These “nicknames” are used to either shorten a long hostname or associate a function with a host. The real name is often called “canonical name” (hence “CNAME”). CNAME must always point to a domain, never to an IP address. Imagine I have this record in my DNS zone:

bojana.dev 120 IN CNAME blog.bojana.dev 

When a DNS software encounters CNAME record, it stops the query for this “nickname” and re-quires for the real name. For the example above, it means the querying will finish once A record for bojana.dev is found.

Pointing a CNAME to another CNAME, is possible (up to seven times, the  eighth target must be a real hostname), but it’s considered inefficient because it requires multiple DNS lookups before the domain can be loaded which ultimately slower experience for the user. MX and NS records cannot point to a CNAME record (they have to point to A or AAAA record).

SRV records

This record specifies the location of the service (a host and a port) within a domain. Services such as VoIP, instant messaging, etc. This DNS record is unique because most other DNS records specify a server or an IP address, whereas the SRV record includes port at that IP address as well.

The format is: service.proto.name [ttl] [IN] SRV pri weight port target

The service is a service defined in the IANA assigned numbers database, proto is either TCP or UDP, name is a domain name to which the SRV record refers, pri is priority, weight is used for load balancing among several servers, port is a port on which service runs, and the target is the hostname of the server that provides the service.

Example :

; main server on port 80, backup on new box, port 8000
_http._tcp SRV 0 0 80 www-server.example.com.
	   SRV 10 0 8000 new-fast-box.example.com.

TXT records

This record adds arbitrary text to the host’s DNS records. Originally, it was intended as a place for human-readable notes. Now, you can also put some machine-readable data into TXT records.

You can create many TXT records for one domain.

Example:

TXT records don’t have any particular format, so they are sometimes used to add information for other purposes without requiring changes to the DNS system itself.

Most DNS records will put a limit on number of TXT records which can be created and how big TXT records can be.

SPF, DKIM, and DMARC records

SPF (Sender Policy Framework), DKIM (DomainKeys Identified Mail), and DMARC (Domain-based Message Authentication, Reporting, and Conformance) are all actually TXT records, and are all standards in an attempt to fight “unsolicited commercial email” aka spam. Going into details about these would require new blogpost.

DNSSEC

Initially, DNS protocol did not considered security. DNS name servers or resolvers could manipulate the content of any DNS record, thus causing the client to receive incorrect information.

RFC 3833 highlight some security threats to DNS, and how DNSSEC addresses these threats.

DNS Security Extensions (DNSSEC) is a security protocol created to mitigate this problem. The protection against attacks is done by digitally signing the data to help ensure its validity. This signing must happen at every level in the DNS lookup process.

DNSSEC implements a hierarchical digital signing policy across all layers of DNS. For example, in the case of a ‘bojana.dev’ lookup, a root DNS Server would sign a key for the .DEV nameserver, and the .DEV nameserver would then sign a key for bojana.dev’s authoritative nameserver.

DNSSEC is also designed to be backward compatible. What that means is, while improved security is of course important and preferred, it has to ensure that traditional DNS lookups still resolve correctly (without added security).

In the part 1 I mentioned the tree structure behind DNS, and root DNS servers at the beginning of this structure. DNSSEC creates a parent-child chain of trust that travels all the way up to the root zone. This chain of trust cannot be compromised at any layer of DNS.

The root zone itself needs to be validated (proven to be free of tampering or fraud). An interesting detail is that this validation of the root zone is actually done by human intervention. In something that’s called Root Zone Signing Ceremony. Selected individuals from around the world are gathered to sign the root DNSKEY in a public and audited way. This process is done every few months.

As mentioned above, DNS servers are vulnerable to broad spectrum of attacks, such as spoofing, DoS (Denial of Service), or interception of private personal information.

Besides DNSSEC, there are additional measures that operator of DNS zone can perform in order to secure their servers. Over-provisioning infrastructure - in simple terms allowing your nameservers to handle multiplies more traffic than expected, in order to overcome DDOS attacks.

Other strategies include using DNS firewall, DNS over TLS and DNS over HTTPS.
Again, DNS security is a broad topic, and would require at least a blogpost of it's own, if not many blogposts ;)

DNS tools

Of course, whether you are administering DNS zones or not, there will come time where you’ll need some kind of way to verify your DNS records are correct and up-to-date. There are numerous tools for analysis, detection etc. of DNS queries. One of them is nslookup. This is, of course, a command line tool. It comes preinstalled on both Windows and Unix systems.

nslookup bojana.dev
Server:  UnKnown
Address:  192.168.100.1

Non-authoritative answer:
Name:    bojana.dev
Address:  157.90.124.251

However, when you want to know some IP behind the domain name, it’s often easier to issue ping command, because it will perform nslookup automatically.

ping bojana.dev

Pinging bojana.dev [157.90.124.251] with 32 bytes of data:
Reply from 157.90.124.251: bytes=32 time=41ms TTL=49
Reply from 157.90.124.251: bytes=32 time=39ms TTL=49

Ping statistics for 157.90.124.251:
    Packets: Sent = 2, Received = 2, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 39ms, Maximum = 41ms, Average = 40ms

dig

(domain information groper) is also a tool for querying DNS servers.
A typical invocation of dig looks like this:
dig @server name type
Usage is as follows:

dig [server] [name] [type]

[server]  The hostname or IP address the query is directed to

[name] DNS (Domain Name Server) of the server to query

[type] The type of DNS record to retrieve. By default (or if left blank), dig uses the A record type
In part 1, I also mentioned that there are 13 root DNS servers, and typically web browsers and operating systems already know about those addresses. If you just enter dig command without parameters, it will return you exactly that list of 13 root DNS servers:

$ dig
; <<>> DiG 9.18.8 <<>>
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58489
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 27

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;.                              IN      NS

;; ANSWER SECTION:
.                       516137  IN      NS      a.root-servers.net.
.                       516137  IN      NS      b.root-servers.net.
.                       516137  IN      NS      c.root-servers.net.
.                       516137  IN      NS      d.root-servers.net.
.                       516137  IN      NS      e.root-servers.net.
.                       516137  IN      NS      f.root-servers.net.
.                       516137  IN      NS      g.root-servers.net.
.                       516137  IN      NS      h.root-servers.net.
.                       516137  IN      NS      i.root-servers.net.
.                       516137  IN      NS      j.root-servers.net.
.                       516137  IN      NS      k.root-servers.net.
.                       516137  IN      NS      l.root-servers.net.
.                       516137  IN      NS      m.root-servers.net.

;; ADDITIONAL SECTION:
a.root-servers.net.     516137  IN      A       198.41.0.4
a.root-servers.net.     516137  IN      AAAA    2001:503:ba3e::2:30
b.root-servers.net.     516137  IN      A       199.9.14.201
b.root-servers.net.     516137  IN      AAAA    2001:500:200::b
c.root-servers.net.     516137  IN      A       192.33.4.12
c.root-servers.net.     516137  IN      AAAA    2001:500:2::c
d.root-servers.net.     516137  IN      A       199.7.91.13
d.root-servers.net.     516137  IN      AAAA    2001:500:2d::d
e.root-servers.net.     516137  IN      A       192.203.230.10
e.root-servers.net.     516137  IN      AAAA    2001:500:a8::e
f.root-servers.net.     516137  IN      A       192.5.5.241
f.root-servers.net.     516137  IN      AAAA    2001:500:2f::f
g.root-servers.net.     516137  IN      A       192.112.36.4
g.root-servers.net.     516137  IN      AAAA    2001:500:12::d0d
h.root-servers.net.     516137  IN      A       198.97.190.53
h.root-servers.net.     516137  IN      AAAA    2001:500:1::53
i.root-servers.net.     516137  IN      A       192.36.148.17
i.root-servers.net.     516137  IN      AAAA    2001:7fe::53
j.root-servers.net.     516137  IN      A       192.58.128.30
j.root-servers.net.     516137  IN      AAAA    2001:503:c27::2:30
k.root-servers.net.     516137  IN      A       193.0.14.129
k.root-servers.net.     516137  IN      AAAA    2001:7fd::1
l.root-servers.net.     516137  IN      A       199.7.83.42
l.root-servers.net.     516137  IN      AAAA    2001:500:9f::42
m.root-servers.net.     516137  IN      A       202.12.27.33
m.root-servers.net.     516137  IN      AAAA    2001:dc3::35

;; Query time: 850 msec
;; SERVER: 172.18.176.1#53(172.18.176.1) (UDP)
;; WHEN: Thu Jan 26 09:59:09 CET 2023
;; MSG SIZE  rcvd: 811
dig output of 13 root DNS servers and their IPs
dig bojana.dev SOA

; <<>> DiG 9.18.8 <<>> bojana.dev SOA
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 47443
;; flags: qr rd ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;bojana.dev.                    IN      SOA

;; ANSWER SECTION:
bojana.dev.             0       IN      SOA     curitiba.ns.porkbun.com. dns.cloudflare.com. 2297766056 10000 2400 604800 3600

;; Query time: 0 msec
;; SERVER: 172.18.176.1#53(172.18.176.1) (UDP)
;; WHEN: Thu Jan 26 09:52:05 CET 2023
;; MSG SIZE  rcvd: 115
example of quering for SOA record for bojana.dev domain

drill

Also a tool to get numerous information out of DNS. It is specifically designed to be used with DNSSEC. The name is sort of a pun on dig. If no arguments are given class defaults to 'IN' and type to 'A'.

bojana@nextcloud:~$ drill -T bojana.dev
.       518400  IN      NS      i.root-servers.net.
.       518400  IN      NS      b.root-servers.net.
.       518400  IN      NS      c.root-servers.net.
.       518400  IN      NS      f.root-servers.net.
.       518400  IN      NS      h.root-servers.net.
.       518400  IN      NS      d.root-servers.net.
.       518400  IN      NS      g.root-servers.net.
.       518400  IN      NS      e.root-servers.net.
.       518400  IN      NS      k.root-servers.net.
.       518400  IN      NS      j.root-servers.net.
.       518400  IN      NS      a.root-servers.net.
.       518400  IN      NS      l.root-servers.net.
.       518400  IN      NS      m.root-servers.net.
dev.    172800  IN      NS      ns-tld5.charlestonroadregistry.com.
dev.    172800  IN      NS      ns-tld3.charlestonroadregistry.com.
dev.    172800  IN      NS      ns-tld2.charlestonroadregistry.com.
dev.    172800  IN      NS      ns-tld1.charlestonroadregistry.com.
dev.    172800  IN      NS      ns-tld4.charlestonroadregistry.com.
bojana.dev.     10800   IN      NS      fortaleza.ns.porkbun.com.
bojana.dev.     10800   IN      NS      salvador.ns.porkbun.com.
bojana.dev.     10800   IN      NS      curitiba.ns.porkbun.com.
bojana.dev.     10800   IN      NS      maceio.ns.porkbun.com.
bojana.dev.     600     IN      A       157.90.124.251
output of drill with argument -T (Trace name from the root down)

This is also a verification of the story about how DNS names are resolved.

DNS might seem as a fairly simple system, however, there are many details, "nuts and bolts" included in order for it to work properly. I mentioned a few pitfalls of DNS and how new updates to the protocol are trying to address them.

Hope you enjoyed the reading, and are know a bit more knowledgable and appreciative of DNS.  ;)
For the end, here's one haiku about DNS. :)