Unused Domain – Add These DNS Records

Why would an unused domain even need any resources records?

It’s common for domains to go unused. Sometimes they’re purchased for a potential idea or project. Other times, it’s to protect a name or trademark, or maybe they’re meant for use internally on a protected and private network. But the internet does weird stuff and sometimes there are steps that should be taken even if these domains aren’t being used.

In August of 2023, @byt3bl33d3r gave a talk at Defcon 31 called “SpamChannel: Spoofing Emails From 2 Million+ Domains and Virtually Becoming Satan,” on how he was able to use Cloudflare Workers to send email as millions of domains and pass many all of the protections meant to stop abuse. The talk is worth watching to see how these systems can be abused. Talk: https://www.youtube.com/watch?v=NwnT15q_PS8.

One takeaway from the talk was to add a null SPF record with “v=spf1 -all” in order to stop this kind of oversight and abuse. This got me thinking: What other DNS records should be in place to protect the abuse of a publicly unused domain?

MX (Mail Exchanger) Records

If the domain isn’t used, we’ll never be receiving email. While this record can simply be left out, we can help tell the internet that’s the case. In fact, RFC 7505 “A ‘Null MX’ No Service Resource Record for Domains That Accept No Mail” provides just this mechanism. A dot ( . ).

Sender Policy Framework, SPF

Of all the resource records, SPF provides the most direct example of how to let others on the web know to not accept email for the domain. In RFC 7208 “Sender Policy Framework (SPF) for Authorizing Use of Domains in Email”, it states, “Publishing SPF records for domains that send no mail is a well-established best practice.” My experience shows that’s not the case. At least as of 2023. But it is right there in the RFC which is helpful.

Domain-based Message Authentication, Reporting, and Conformance, DMARC

This may be overkill, but in the case pointed in the talk, I believe it’s simply extra insurance to go ahead and configure. And, like SPF, configuration helps everybody else detect the abuse and is simply a good netizen practice. For DMARC, there is not a “best practice” for this use case outlined within RFC 7489: Domain-based Message Authentication, Reporting, and Conformance (DMARC). However, it’s pretty straight forward to tell the world to reject anything for this domain with the declaration below.

v=DMARC1 → Required. This directive is always the same and required. Simply tells the version, of which there is only one.

p=reject → Required. This is the Requested Mail Receiver Policy and is required for any DMARC record. “Reject” simply tells mail receivers to reject email that fails the DMARC mechanism check.

adkim=s; aspf=s These defines strict (opp. relaxed) conformance/alignment with SPF or DKIM as required. Because there are no DKIM records for this domain and the SPF doesn’t permit a valid sender, these should fail.

spNote: This directive provides a policy if we were using subdomains. In its absence, all subdomains are covered by the primary policy so this isn’t required.

pctNote: This provides a mechanism for mail receivers to apply the policy to a portion of mail received from the sending domain. This is helpful when testing out the impact of a new policy adjustment, especially for high volume senders. Default is to apply to 100 percent so this directive is unnecessary.

DomainKeys Identified Mail, DKIM

DKIM uses selectors to provide a mechanism of providing multiple public keys per signing domain. You can find the details of this within RFC 4871: DomainKeys Identified Mail (DKIM) Signatures. Because of this, when DKIM is used, it’s common to find many different selectors in use. And while some selectors are common (e.g. selector1, selector2, dkim, k1, google), there is no “default” selector we can provide a junk or null value to in order to ensure this check fails. However, requiring DKIM alignment within the DMARC policy should tell a receiving party to require valid DKIM which should always fail, thereby keeping the domain from being abused via email.

Certification Authority Authorization, CAA

CAA records allow a DNS domain name holder to specify one or more Certification Authorities authorized to issue certificates for that domain. The absence of a CAA record enables the domain holder to use any CA they want. Because this is an unused domain, there should never be a certificate issued (at least publicly) for any resources in this domain. RFC 8659: DNS Certification Authority Authorization (CAA) Resource Record provides a mechanism for disallowing CAs following the CAA standard from issuing certificates by creating a CAA record with a value of a semicolon only ( ; ).

Note: For private use of a domain name, an additional benefit of using this mechanism to block certificate issuance is with Certificate Transparency (CT) information leakage. RFC 9162 defines CT as a system of public logs that seek to eventually record all certificates issued by publicly trusted certificate authorities. Blocking them from issuing certificates aids in protecting the private use of certificates and unintended information disclosure.

Root Domain Records: A, AAAA

These records are probably unnecessary and simply personal preference. There are really two acceptable choices here: 1) no records at all, or 2) use of addresses that won’t work on a public or private network. I’ve seen folks recommend private address spaces such as or or However, these records could be abused as they would still potentially resolve to an address that is in use on a private network. If we’re going to use an address for these records, we want it to point to an address that cannot be used. Fortunately, engineers provided options for this in the ipv4 and ipv6 address space.

ipv4 root domain A record or “@”: RFC 5737: IPv4 Address Blocks Reserved for Documentation sets aside for use in documentation and advises operators to block or otherwise make inoperable, these addresses on private, public, and local networks.

ipv6 root domain AAAA record: 2001:DB8:: RFC 3849: IPv6 Address Prefix Reserved for Documentation sets aside 2001:DB8::/32 for use in documentation and advises operators to block or otherwise make inoperable, these addresses on private, public, and local networks.

Other Considerations

www CNAME record: There is a lot of debate about whether to use or not use www. The reality is that many things, including some users, prepend a domain name with www for a myriad of reasons. I usually throw this in there to save them a step and give them the domain root answer right away. And with CNAME flattening, I don’t see any downside to including this.

Wildcard DNS: There may be benefits to using a wildcard dns record, if your provider supports this functionality. This will always provide an answer for anything at your domain instead of an NXDOMAIN response.

The DNS Security Extensions: DNSSEC

And of course, none of this ensures the party querying your domain gets a trusted response unless you are signing your zones. Make sure to enable DNSSEC on those zones. If you ever end up using the domain, it’s one less thing you’ll forget about and later have to enable anyway. More info on DNSSEC.

Putting It All Together

Here’s an example zone file with all the recommendations.

Optional USB Device in Virtual Machine Manager

To make a USB Host Device optional on startup within KVM, edit the XML and add startupPolicy="optional" to the source node. This will ensure your usb stick, yubikey, or whatever, it won’t stop your VM from booting if it isn’t present.


<hostdev mode="subsystem" type="usb" managed="yes">
  <source startupPolicy="optional">
    <vendor id="0x1050"/>
    <product id="0x0402"/>
  <address type="usb" bus="0" port="4"/>
</hostdev>Code language: HTML, XML (xml)

Application Guard Testing with Virt-Manager

Received a BSOD with error code 0xc0000225 on a Windows 10 (and 11) VM when enabling the Hyper-V role to do some testing with Microsoft Defender Application Guard. This VM runs on a Rocky Linux host and I typically use Virt-Manager to handle my VMs. Two changes were necessary to get nested Hyper-V working with virt-manager:

  1. virt-xml <VM-NAME> –edit –cpu host-passthrough
  2. sudo modprobe kvm_intel nested=1
    1. kvm_amd for AMD processors
    2. You can check the value here:
      1. cat /sys/module/kvm_intel/parameters/nested

Once that was done, Hyper-V took great, and I could test Application Guard on the VM.

krbtgt password reset – denied due to complexity

I was cleaning up a new directory and found the krbtgt account password hadn’t been reset for over two decades. When I tried resetting it, I could not due to complexity requirements.

Each DC in an AD domain runs a Kerberos Distribution Center (KDC) service that handles all Kerberos ticket requests. AD uses the krbtgt account for Kerberos tickets. This account is an important one and can be used in attacks, such as Golden Ticket attacks: https://techcommunity.microsoft.com/t5/security-compliance-and-identity/how-microsoft-advanced-threat-analytics-detects-golden-ticket/ba-p/250341


Upon trying to reset this password, I received the following error. I was using a 32-character randomly generated password that has all the complexity bits possible. Digging around, I stumbled upon this article from Microsoft: https://docs.microsoft.com/en-us/troubleshoot/windows/win32/change-krbtgt-password-may-fail

It states:
“If a custom password filter (for example, passfilt.dll) is installed on a domain controller, you may receive the following error when trying to change the password for the krbtgt account.”

“This occurs because there is special logic when changing the password for krbtgt. While the Active Directory Users and Computers (dsa.msc) snap-in allows you to enter a password, it won’t be used when changing the password. Instead, the Active Directory creates a long string of random bits to use as the password. Since this string contains random data and not Unicode characters, it fails the typical tests included in password filters. These tests typically include checking to see if the password contains a certain combination of upper and lower case letters, numbers, and punctuation.”

I checked. And sure enough, there was a password filter.

The Fix

Found in this post on Spiceworks: https://community.spiceworks.com/topic/2258213-we-are-unable-to-reset-the-krbtgt-password-after-installed-openpasswordfilter

Create a new Fine-Grained Password Policy with complexity disabled, and add DOMAIN\krbtgt as a subject of the FGPP and try again.

The Spiceworks post shows the details on Powershell, so I’ve provided the GUI version. Hope this saves somebody a headache or two.

LAB: WAN Issues w/ Realtek + PFSense

It’s a pretty common issue. Realtek devices are inexpensive an prolific but they’re flaky and not recommended by most. Coupled with pfsense, one can have a pretty solid lab if you can get them working reliably. I went down the path of building out a new lab with a gigabyte box as a pfsense one-arm-router. I paired it with a managed PoE switch running a few Ubiquiti APs so I could power and pull networks from some IoT devices I was researching.

Every time my nic was under load, my WAN interface would go down. Reloading the interface was a quick fix but it was one needing a more permanent fix.

This was the solution: https://forum.netgate.com/topic/135850/official-realtek-driver-binary-1-95-for-2-4-4-release/19


Unzip & Place “if_re.ko” file in the “/boot/kernel” folder

Ensure ownership and permissions on the if_re.ko file are:

  • chown root:wheel if_re.ko
  • chmod 0555 if_re.ko

Add this line to “/boot/loader.conf“:

  • if_re_load=”YES


Once you reboot, you can run kldstat to verify the driver is loaded. Most folks were having issues with “smart quotes” on their copy-pastes.

This solved all the stability issues I was experiencing in my lab.


PFSense 2.4.4 on an ACEPC T11

I bought a silver ACEPC T11 for doing some lab work for $127 (link). It sports an Intel Cherry Trail Atom Z8350, quad-core CPU, 4GB of RAM, and 64GB emmc, and a dual-band 2.4ghz and 5ghz wireless card. I tried booting off the pfsense media and it kept hanging at ppc0: cannot reserve I/O port range. After poking around, I ran across this article: https://forum.netgate.com/topic/109447/zotac-ci323-installation-controller-failures/16

I rebooted and selected 3. [Esc]ape to loader prompt on the boot menu. At the OK prompt, I entered:

set hint.uart.0.disabled="1"
set hint.uart.1.disabled="1"
bootCode language: JavaScript (javascript)

It booted right up and pfsense installed without any issues.

Next, I’ll be ripping it open and installing external wireless adapters and an SSD for storing pcaps.

dns.msftncsi.com DNS Requests Every Few Seconds

Over the weekend, I updated my wireless router to the latest revision of ASUSWRT-Merlin. I also decided to update my DietPi Pi-hole to their latest builds. Due to a full code rewrite of Dietpi, it meant a complete rebuild for that system. The release of ASUSWRT-Merlin also suggested resetting to factory defaults due to some major changes. Everything was about to be new again.

Once I got everything rebuilt and running, I noticed requests coming from my firewall to my dietpi every 10 seconds or so for dns.msftncsi.com. I immediately assumed this was some Microsoft telemetry noise on my network from MS NLA. However, the queries were coming directly from my firewall which seemed odd. Another search led me to a post on the Pi-hole discourse. After I ran nvram show | grep dns_probe, it was clear I found the culprit.

admin@gw:/tmp/home/root# nvram show | grep dns_probe
dns_probe_content= fd3e:4f5a:5b81::1

I ran the following three lines and confirmed the traffic stopped. No reboot was necessary. The first post I read recommended setting dns_probe_content to and dns_probe_host to “” (effectively blank). I later found a post by RMerlin that explains setting dns_probe_content to blank disables the watchdog service but effectively disables the dual WAN feature. It would make sense that dual WAN would require a watchdog service. So, if you use dual WAN, don’t do this. Otherwise, you should be fine.

admin@gw:/tmp/home/root# nvram set dns_probe_content=
admin@gw:/tmp/home/root# nvram set dns_probe_host=
admin@gw:/tmp/home/root# nvram commit

RPM/yum Database Corruption

Jumped onto my server and noticed a few out of date packages. A quick % sudo yum update reported the following:

error: rpmdb: BDB0113 Thread/process 12323/139745043400512 failed: BDB1507 Thread died in Berkeley DB library
error: db5 error(-30973) from dbenv->failchk: BDB0087 DB_RUNRECOVERY: Fatal error, run database recovery
error: cannot open Packages index using db5 - (-30973)
error: cannot open Packages database in /var/lib/rpm

Fortunately, the fix was easy:
% sudo rpm --rebuilddb

Once complete, yum update worked like new.

Weekend Reading – April 22, 2016

Blogs / News