DNS Hardening
A Brief Overview of DNS Hardening
What is DNS?
Domain Name System (DNS) is a protocol designed to translate IP addresses (IPv4/6) into human-readable addresses—e.g., search.tuckettlab.xyz.
In practice the reverse: human-readable addresses > IP addressesWithout DNS, navigating the internet would be needlessly exhausting—requiring users to manually enter an IP address every time they were to access web content.
Additionally, dynamic mapping executed via DNS allows for essential accessibility functions like geo-availability—providing content within relevant geographic locations—significantly accelerating your web traffic.
How Does DNS Work?
DNS is a highly structured and hierarchical protocol—relying on several chains of trust to translate addresses.
Root Servers
- The top of the rung, served by 13 root server identifiers (12 organizations) distributed worldwide.
- Does not store zone records for domains, but they return referrals to the authoritative nameservers for the requested TLD (not individual domains): .xyz(.).
Top-Level Domains
- Second, just below root servers—housing domain extensions like: .edu, .com, .net, and .xyz.
- TLD servers return referrals to authoritative nameservers for second-level domains.
Second-Level Domains
- Third in the chain, delegated (by authoritative servers) and purchasable from domain registrars; second-level domains are registered under a TLD: tuckettlab.xyz.
- SLDs lie within authoritative servers, essentially where your DNS records actually exist (zone): A/AAAA—pointing to valid IP addresses.
Third-Level Domains
- Fourth in the chain, subdomains (within parent zone) managed by DNS records (CNAME, A, AAAA): search.tuckettlab.xyz
- Commonly used for load balancing and service separation: mail.tuckettlab.xyz (MX).
Host/FQDN
- Last step: produces a fully qualified domain name (FQDN), which uniquely identifies a host—accessible to users.
- For users: a recursive DNS server queries step by step: root > top-level domain server > second-level authoritative > subdomain (third-level domain) > resolver returns the corresponding record to the client.
Response Codes
NXDOMAIN: A response code representing the absence or non-existence of a domain.
- Authoritative servers for the TLD respond NXDOMAIN if the entire SLD doesn’t exist under its respective TLD; otherwise, NXDOMAIN comes from the authoritative SLD server.
NODATA (NOERROR/Empty): A response code indicating that the domain does exist, but no records of the requested type are present (A is present, AAAA is not).
Example Queries
1### Successful Query ###
2dig NS search.tuckettlab.xyz
3
4; <<>> DiG 9.18.30-0ubuntu0.24.04.2-Ubuntu <<>> NS search.tuckettlab.xyz
5;; global options: +cmd
6;; Got answer:
7;; ->>HEADER<<- opcode: QUERY, status: !!!NOERROR!!!, id: 51001
8;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
9
10;; OPT PSEUDOSECTION:
11; EDNS: version: 0, flags:; udp: 65494
12;; QUESTION SECTION:
13;search.tuckettlab.xyz. IN NS
14
15;; AUTHORITY SECTION:
16tuckettlab.xyz. 150 IN SOA ns1.vultr.com. dnsadm.choopa.com. 0 10800 3600 604800 3600
17
18;; Query time: 1 msec
19;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
20;; WHEN: Sat Aug 30 11:52:13 MDT 2025
21;; MSG SIZE rcvd: 113
22
23### Unsuccessful Query ###
24dig NS ?.xyz
25
26; <<>> DiG 9.18.30-0ubuntu0.24.04.2-Ubuntu <<>> NS ?.xyz
27;; global options: +cmd
28;; Got answer:
29;; ->>HEADER<<- opcode: QUERY, status: !!!NXDOMAIN!!!, id: 61057
30;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
31
32;; OPT PSEUDOSECTION:
33; EDNS: version: 0, flags:; udp: 65494
34;; QUESTION SECTION:
35;?.xyz. IN NS
36
37;; AUTHORITY SECTION:
38xyz. 773 IN SOA ns0.centralnic.net. hostmaster.centralnic.net. 3000828297 900 1800 6048000 3600
39
40;; Query time: 80 msec
41;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
42;; WHEN: Sat Aug 30 11:55:18 MDT 2025
43;; MSG SIZE rcvd: 99
DNS Records
Within the managed zone, records are applied to guide users towards specific services.
Common Records
Concise for the Sake of Brevity- NS - Name Server (Delegates Authority for domains).
- SOA - Start of Authority (Provides administrative information about the zone)
- A/AAAA - IPv4/6 Addresses (Points to the designated IP address.).
- CNAME - Canonical Name (Points a name to another name; A/AAAA record is after the target).
- MX - Mail Record (Normally points to mail subdomain).
- PTR - Pointer (Reverse DNS is configured by your IP provider (VSP/ISP), not on forward zone; IP > domain).
- TXT - Text (Commonly used for SPF/DKIM/DMARC for mail; can be informative).
- CAA - Certificate Authority Authorization (Permits which certificate authorities can permit SSL/TLS Certs).
- DNSKEY - Domain Name System Key (Stores public key in zone; used for DNSSEC validation).
- DS - Delegation Signer (Stored in parent zone, contains hash of child zone’s DNSKEY record).
- CDNSKEY/CDS - Child DNSKEY/DS (Utilized for child to publish key details to parent zone).
TXT-Related Records
- SPF - Sender Policy Framework (Specifies which mail servers are authorized To send mail).
- DKIM - DomainKeys Identified Mail (Cryptographic signature system for email content/headers).
- DMARC - Domain-based Message Authentication (Instructs receiving mail servers to handle mail that fails SPF/DKIM checks; may report to admin’s email).
TTLs
When configuring DNS zones, you will have the option to give records a Time to Live (TTL)—representing the number of seconds a DNS record is cached before it is re-queried by an authoritative server.
Record Representation
1### ! FORMAT ! ###
2Domain (Root:.) TTL Class Record Data Priority
3
4### NS ###
5dig NS tuckettlab.xyz
6
7tuckettlab.xyz. 300 IN NS ns1.vultr.com.
8tuckettlab.xyz. 300 IN NS ns2.vultr.com.
9
10## SOA ##
11dig SOA tuckettlab.xyz
12
13tuckettlab.xyz. 300 IN SOA ns1.vultr.com. dnsadm.choopa.com. 0 10800 3600 604800 3600
14
15### A/AAAA ###
16dig A tuckettlab.xyz AAAA tuckettlab.xyz
17
18tuckettlab.xyz. 3600 IN A 149.28.67.27
19tuckettlab.xyz. 3600 IN AAAA 2001:db8::25
20
21### CNAME ###
22dig CNAME www.tuckettlab.xyz
23
24www.tuckettlab.xyz. 3600 IN CNAME tuckettlab.xyz.
25
26### MX ###
27dig MX tuckettlab.xyz
28
29tuckettlab.xyz. 3600 IN MX 10 mail.server.net.
30
31### PTR ###
32dig -x 149.28.67.27
33
3427.67.28.149.in-addr.arpa. 3555 IN PTR tuckettlab.xyz.
35
36### CAA ###
37dig CAA tuckettlab.xyz
38
39tuckettlab.xyz. 3600 IN CAA 0 issue "tlsprovider.net"
40tuckettlab.xyz. 3600 IN CAA 0 issuewild "tlsprovider.net"
41tuckettlab.xyz. 3600 IN CAA 0 iodef "mailto:admin@admin.net"
42
43
44### DNSKEY/DS ###
45dig @9.9.9.9 DNSKEY tuckettlab.xyz DS tuckettlab.xyz
46
47tuckettlab.xyz. 2761 IN DNSKEY 257 3 13 UguAJ1bTfrBPNp+jHQ2oZNaPSUsUHaCnwRW+Wcxaf2BueGEmnMGAINj2 1b7gANfBBqqXoB6dGTeOBHfvjAvOdA==
48tuckettlab.xyz. 3600 IN DS 35175 13 4 865FE510C4CE390FF7285308B9351880A84039F1D75ACA278EF37F9D 71F605D8EC69C87E2F5660CA8BC5BC477A715868
49tuckettlab.xyz. 3600 IN DS 35175 13 2 871FD8CC8AFC7A1A6C60558112837CD7F288A20CC7F639709AD4A703 9C21E6B9
50
51### TXT Mail Records ###
52dig TXT tuckettlab.xyz TXT selector._domainkey.tuckettlab.xyz TXT _dmarc.tuckettlab.xyz
53
54tuckettlab.xyz. 3600 IN TXT "v=spf1 include:_spf.mail.net ~all"
55_dmarc.tuckettlab.xyz. 3600 IN TXT "v=DMARC1; p=quarantine"
56selector._domainkey.tuckettlab.xyz. 3600 IN TXT "v=DKIM1; k=key type; p=pubkey"
Hardening DNS
Now this is where the fun begins...Hardening DNS is quite a bit more straightforward than dealing with content security policies and general systems.
Most registrars allow you to manually edit your zone; if not, find a more consumer-friendly registrar.
For hardening purposes, some registrars hide DNSSEC behind a paywall; make sure to do your research.
If you are using a VPS for your infrastructure, it may be best to move your zone to your VPS provider—supplying a unified management pane with easy DNSSEC support.
A/AAAA
It is best to keep these records current and remove anything that may be used by malicious actors.
Many providers offer built-in proxies, where you can mask your origin traffic behind another IP address.
I avoided AAAA records because they may increase my attack surface—exposing an additional interface that is susceptible if not hardened.CNAME
CNAME records do not resolve directly—requiring two lookups instead of one—slowing resolution (negligible).
This may not be an inherent issue, but wildcard records should be avoided because this opens your zone to a litany of abuse (largely impersonation).
Additionally, it can make administration far more difficult, as each chain must be validated under DNSSEC; unstable in general.
MX
Depending on your use case, you may want this enabled or disabled; are you using email with this domain?
If your domain does not require email, setting a NULL MX record prevents any attempts at impersonation.
MX TXT Records
Setting your SPF TXT record to a hard fail further cements your defense against potential forgery (-all HARD vs ~all SOFT).
Sane DMARC TXT values are also incredibly important for securing your email.
With that in mind, DMARC has quite a selection of potential options:
-
Policy (p): should not be set to quarantine; it is best to outright REJECT (following a staging process) to prevent against phishing.
-
Subdomain Policy (sp): behaves in a similar fashion—but only covering subdomains; if not set, subdomains may default back to a weaker policy.
-
Alignment Mode for DKIM (adkim): is a great complement towards a secure DKIM setup; it may contain the values strict (s) or relaxed (r).
-
Alignment Mode for SPF (aspf): behaves quite similarly to adkim but is a reinforcement for your SPF TXT record; again, it may contain values strict (s) or relaxed (r).
-
The Percentage of Messages (pct): is related to how many potential messages these policies apply to; optimal if set to 100 (100%).
-
Aggregate Reports (rua): may be enabled, which includes reporting for sent mail and DKIM/DMARC/SPF stats.
-
Forensic Reports (ruf): may also be enabled—sending immediate notices for DMARC evaluation failures (far noisier than rua).
-
The Failure Options tag (fo): complements both reporting features, ranging in values from 0 (both SPF/DKIM fail), 1 (either SPF/DKIM fails), d (DKIM), s (SPF).
For my setup, I do not want ANY mail to be sent from this domain—as this is for self-hosted services ONLY.
DKIM will not exist, nor possibly be resolved.
### MX Record - NO MAIL ###
tuckettlab.xyz. 3600 IN MX 0 .
### MX TXT Records - Complements NO MAIL Policy (No rua/ruf) ###
tuckettlab.xyz. 1736 IN TXT "v=spf1 -all"
_dmarc.tuckettlab.xyz. 1818 IN TXT "v=DMARC1; p=reject; sp=reject; adkim=s; aspf=s; pct=100"
### DMARC With Reporting ###
_dmarc.tuckettlab.xyz. 1818 IN TXT "v=DMARC1; p=reject; sp=reject; rua=mailto:admin@tuckett.xyz; ruf=mailto:admin@tuckett.xyz; fo=1; adkim=s; aspf=s; pct=100"
DNSSEC
I cannot stress how important it is to enable DNSSEC for your domains.
Doing so provides:
- Authenticity: (Supplies strong cryptographic context for whether the record truly came from the authoritative server).
- Integrity: (Prevents MITM tampering; guards DNS responses in transit).
- Anti-Cache Poisoning: (Impersonators CANNOT inject falsified DNS data into resolvers).
It is as simple as configuring a few keys from your registrar and publishing them within your zone.
### Enable DNSKEY and DS Record for DNSSEC (USE STRONG ALGORITHMS) ###
tuckettlab.xyz. 3600 IN DNSKEY 257 3 13 UguAJ1bTfrBPNp+jHQ2oZNaPSUsUHaCnwRW+Wcxaf2BueGEmnMGAINj2 1b7gANfBBqqXoB6dGTeOBHfvjAvOdA==
tuckettlab.xyz. 214 IN DS 35175 13 4 865FE510C4CE390FF7285308B9351880A84039F1D75ACA278EF37F9D 71F605D8EC69C87E2F5660CA8BC5BC477A715868
tuckettlab.xyz. 214 IN DS 35175 13 2 871FD8CC8AFC7A1A6C60558112837CD7F288A20CC7F639709AD4A703 9C21E6B9
CAA
Also a massive oversight; CAA records prevent rogue issuance by malicious CAs.
CAA flags are set in 8-bit values (0-255); 0 is default (non-critical)—which allows soft fails (sometimes needed for compatibility).
128 is functionally the only value worth using, as it is treated as critical and far more strict (must be understood by CAs).
Both issue and issuewild are utilized for SSL/TLS distinction; wildcard certs may be utilized, though they are not advised.
# Sane Value - Only Allows Strict Issuance From Let's Encrypt ###
tuckettlab.xyz. 2103 IN CAA 128 issue "letsencrypt.org"
# Disable Wildcard Certs - Prevents Against Wildcard Abuse (; = NO CAs) ###
tuckettlab.xyz. 2103 IN CAA 128 issuewild ";"
# Incident Object Description Exchange Format - Instructs CAs Where to Send Reports ###
tuckettlab.xyz. 2103 IN CAA 128 iodef "mailto:admin@tuckett.xyz"
TXT Records
It may be useful to include important information within your TXT records, as most text may be inserted.
I included important statements, checksums, onion location(s) (if not pulled by HTTP header), and my GPG info.### My TXT Records ###
tuckettlab.xyz. 1736 IN TXT "gpg-mirror=https://github.com/masontuckett/masontuckett.gpg"
tuckettlab.xyz. 1736 IN TXT "gpg=https://masontuckett.xyz/masontuckett.gpg"
tuckettlab.xyz. 1736 IN TXT "gpg-pubkey-fpr=7272B8036060E4590218A95D11F58765E7B21193"
tuckettlab.xyz. 1736 IN TXT "onion-search=ujozjm7regwuwszlcyx2g3jn6bgegrxk5x72q3om6sxb7kq7x5fgcwqd"
tuckettlab.xyz. 1736 IN TXT "privacy-policy=https://masontuckett.xyz/privacy-policy.txt"
tuckettlab.xyz. 1736 IN TXT "onion-library=ekybwg2m7fgocpnr5ofjjo2lrfunptquipqihfaxodand4qfm6rc3gqd"
tuckettlab.xyz. 1736 IN TXT "auth-statement=https://masontuckett.xyz/tor-mirror-statement.txt"
tuckettlab.xyz. 1736 IN TXT "sha512sums=https://masontuckett.xyz/sha512-hashes.txt"
Live Demonstration
1;; ANSWER SECTION:
2tuckettlab.xyz. 3600 IN A 149.28.67.27
3tuckettlab.xyz. 3600 IN RRSIG A 13 2 3600 20250911000000 20250821000000 35175 tuckettlab.xyz. pLFdcvumIdn66a+KwNtzpAdXrL2/QoBaKK4Ah2+mb0c0uoh81gZMlHnI yHO3q4+D8ZiokKKGg+GOllTRFu0REw==
4tuckettlab.xyz. 300 IN NS ns2.vultr.com.
5tuckettlab.xyz. 300 IN NS ns1.vultr.com.
6tuckettlab.xyz. 300 IN RRSIG NS 13 2 300 20250911000000 20250821000000 35175 tuckettlab.xyz. NKfKYWEfEC6QKsLpL8Skb948Mj2uCxl3YgUkweaFrBix97lZdqOGzxH/ XuUUry62xW/8x9SCZi+xfv7Zh7JLxA==
7tuckettlab.xyz. 300 IN SOA ns1.vultr.com. dnsadm.choopa.com. 0 10800 3600 604800 3600
8tuckettlab.xyz. 300 IN RRSIG SOA 13 2 300 20250911000000 20250821000000 35175 tuckettlab.xyz. zsnBppGRceCk6wVxB2ilh61eCEODg8zR4AHr/RhcCSjnvjjlc+rme1wP RAFZYN/0tmO2jTPsyE2GjgXNxnZ0tw==
9tuckettlab.xyz. 3600 IN MX 0 .
10tuckettlab.xyz. 3600 IN RRSIG MX 13 2 3600 20250911000000 20250821000000 35175 tuckettlab.xyz. gt6nQjDrYIrXUhWV75i3BABNiGFV3/1NVeF1n8j1wrjZs81IC6umI66l NEHYfqq702CXnaq5kAe4qv/CBg3u6g==
11tuckettlab.xyz. 3600 IN TXT "v=spf1 -all"
12tuckettlab.xyz. 3600 IN TXT "sha512sums=https://masontuckett.xyz/sha512-hashes.txt"
13tuckettlab.xyz. 3600 IN TXT "auth-statement=https://masontuckett.xyz/tor-mirror-statement.txt"
14tuckettlab.xyz. 3600 IN TXT "privacy-policy=https://masontuckett.xyz/privacy-policy.txt"
15tuckettlab.xyz. 3600 IN TXT "gpg-mirror=https://github.com/masontuckett/masontuckett.gpg"
16tuckettlab.xyz. 3600 IN TXT "onion-library=ekybwg2m7fgocpnr5ofjjo2lrfunptquipqihfaxodand4qfm6rc3gqd"
17tuckettlab.xyz. 3600 IN TXT "gpg=https://masontuckett.xyz/masontuckett.gpg"
18tuckettlab.xyz. 3600 IN TXT "onion-search=ujozjm7regwuwszlcyx2g3jn6bgegrxk5x72q3om6sxb7kq7x5fgcwqd"
19tuckettlab.xyz. 3600 IN TXT "gpg-pubkey-fpr=7272B8036060E4590218A95D11F58765E7B21193"
20tuckettlab.xyz. 3600 IN RRSIG TXT 13 2 3600 20250911000000 20250821000000 35175 tuckettlab.xyz. 6TLPYOEnXr6ml3B7aTluAwR71fGfit6BQ93Lwumoq6VZZPu2fqd1r05i 8yEZa6tMVCJMhwDKb1GPhyXyWzmNAw==
21tuckettlab.xyz. 300 IN NSEC _dmarc.tuckettlab.xyz. A NS SOA MX TXT RRSIG NSEC DNSKEY CAA
22tuckettlab.xyz. 300 IN RRSIG NSEC 13 2 300 20250911000000 20250821000000 35175 tuckettlab.xyz. qTvUILjKw2EToMEjOiBE82s+frvHy4HL100cwCXNGxWVXbJvY3PmfTuy OVyBqpjw4NBHV26ORaNuuIfV5NB0yg==
23tuckettlab.xyz. 3600 IN DNSKEY 257 3 13 UguAJ1bTfrBPNp+jHQ2oZNaPSUsUHaCnwRW+Wcxaf2BueGEmnMGAINj2 1b7gANfBBqqXoB6dGTeOBHfvjAvOdA==
24tuckettlab.xyz. 3600 IN RRSIG DNSKEY 13 2 3600 20250911000000 20250821000000 35175 tuckettlab.xyz. wrdN1qTW2ZfWZ1wX8I5q7ryFfVQH71LZAUEqN6xeKY+AQRy4TJiU/IEi gxuCoPXnxS1D7N9XHwMip0rUOpie0A==
25tuckettlab.xyz. 3600 IN CAA 128 iodef "mailto:admin@tuckett.xyz"
26tuckettlab.xyz. 3600 IN CAA 128 issuewild ";"
27tuckettlab.xyz. 3600 IN CAA 128 issue "letsencrypt.org"
28tuckettlab.xyz. 3600 IN RRSIG CAA 13 2 3600 20250911000000 20250821000000 35175 tuckettlab.xyz. +dIuWxaDGXHeN7U/KlzxZOKZATc5a6Mrj7HzcGn88nAJ52dNPj4Suzud SNwZxeg9em8Vb2fVOqifpK/1FbAZrg==
29
30;; Query time: 32 msec
31;; SERVER: 8.8.8.8#53(8.8.8.8) (TCP)
32;; WHEN: Sat Aug 30 16:18:37 MDT 2025
33;; MSG SIZE rcvd: 1878
34
35;; ANSWER SECTION:
36_dmarc.tuckettlab.xyz. 3600 IN TXT "v=DMARC1; p=reject; sp=reject; adkim=s; aspf=s; pct=100"
37
38;; Query time: 259 msec
39;; SERVER: 9.9.9.9#53(9.9.9.9) (UDP)
40;; WHEN: Sat Aug 30 16:16:10 MDT 2025
41;; MSG SIZE rcvd: 118
Post-Hardening Evaluation
I believe if you are serious about your security, it is both intrinsically and extrinsically very important to verify your current security posture against other well-known sites/platforms.
I may plan on migrating my infrastructure to a platform that supports NSEC3 (currently stuck at NSEC)—which can prevent trivial zone walking.
For comparison: "Cyber Guru" John Hammond's Training Platform. 1;; ANSWER SECTION:
2justhacking.com. 3524 IN TXT "v=spf1 include:_spf.google.com ~all"
3justhacking.com. 3524 IN TXT "google-site-verification=WizBgAHBHgn4CAkraQKDWWpGqWqGCVianppbA3tfDGw"
4justhacking.com. 14324 IN MX 5 alt1.aspmx.l.google.com.
5justhacking.com. 14324 IN MX 10 alt4.aspmx.l.google.com.
6justhacking.com. 14324 IN MX 5 alt2.aspmx.l.google.com.
7justhacking.com. 14324 IN MX 10 alt3.aspmx.l.google.com.
8justhacking.com. 14324 IN MX 1 aspmx.l.google.com.
9justhacking.com. 21524 IN SOA ns-cloud-a1.googledomains.com. cloud-dns-hostmaster.google.com. 12 21600 3600 259200 300
10justhacking.com. 21524 IN NS ns-cloud-a2.googledomains.com.
11justhacking.com. 21524 IN NS ns-cloud-a3.googledomains.com.
12justhacking.com. 21524 IN NS ns-cloud-a4.googledomains.com.
13justhacking.com. 21524 IN NS ns-cloud-a1.googledomains.com.
14justhacking.com. 14324 IN A 64.23.145.242
15
16;; Query time: 16 msec
17;; SERVER: 8.8.8.8#53(8.8.8.8) (TCP)
18;; WHEN: Sat Aug 30 16:22:17 MDT 2025
19;; MSG SIZE rcvd: 479