Skip to content

allanninal/dns-fixes

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DNS and Domains Fixes

Small, tested Python and Node.js scripts that detect and repair real problems across DNS and domains. Missing or wrong records, broken email authentication (SPF, DKIM, DMARC), nameserver and delegation mismatches, TTL and propagation surprises, DNSSEC gaps, certificates and domains about to expire, CAA blocking issuance, and dangling records that invite subdomain takeover.

Every fix is safe by default. The scripts start in a dry run mode that reports what they would do, so you can read the plan before anything writes.

By Allan Niñal — AI Solutions Engineer. I build AI powered tools, data products, and AWS automation. Full write ups with diagrams for each fix live at allanninal.dev/dns.

Follow on GitHub Tests

How the scripts work

These scripts check DNS and domain health with standard tools, not a store API. Python uses dnspython for lookups, requests for RDAP/WHOIS and the provider API, and the ssl module for certificates; Node uses the built-in dns and tls modules and fetch. Repairs go through a DNS provider API (Cloudflare, AWS Route 53). The decision logic in every fix is a pure function with no network, so it is unit tested.

Setup

Set the environment variables a fix needs. You only need provider credentials for the repair fixes; the checks need nothing but a domain name.

export DNS_DOMAIN="yourdomain.com"
export CLOUDFLARE_API_TOKEN="your token"   # only for repair fixes
export DRY_RUN="true"   # start safe

Python needs pip install requests pytest. Node needs Node 18 or newer (the scripts use the built-in fetch, no packages).

The fixes

Fix What it does Type Guide
registrar-zone-nameserver-mismatch Registrar NS glue differs from the authoritative zone NS set. Script compares WHOIS/RDAP NS against live NS query. Diagnostic Read
missing-subdomain-delegation-glue Parent zone lacks NS records delegating a subdomain. Script checks parent zone delegation against child zone SOA/NS. Diagnostic Read
partial-nameserver-cutover-split-answers Old and new nameservers both listed at registrar during migration. Script queries each NS directly and diffs responses. Reconciler Read
hosted-zone-recreated-ns-mismatch Deleting and recreating a zone assigns new NS that no longer match registrar delegation. Script cross-checks zone NS against registrar NS. Reconciler Read
missing-address-record-nxdomain Hosted zone lacks an address record for the queried name. Script resolves the name and reports the missing record. Diagnostic Read
cname-at-zone-apex A literal CNAME at the root breaks required apex records. Script detects apex CNAME and confirms flattening resolved correctly. Repair Read
cname-coexistence-violation A CNAME shares a hostname with MX, TXT, or A records, which is invalid. Script scans the zone for coexistence violations. Diagnostic Read
duplicate-conflicting-records Two A records or a CNAME plus another type exist at one name causing undefined resolution. Script fetches the record set and flags duplicates. Diagnostic Read
cname-to-a-type-change-conflict Converting a CNAME to an A record fails unless the old record is deleted first. Script orders deletes before creates when reconciling. Repair Read
www-apex-mismatch Only www or only apex is set up, so the other variant fails to resolve or serves different content. Script resolves both and compares. Reconciler Read
wildcard-catch-all-exposure A broad wildcard resolves every undefined subdomain, masking typos or takeovers. Script enumerates wildcard scope and flags apex-level wildcards. Diagnostic Read
custom-domain-dns-verification-failure Apex A records or CNAME target do not match the host's required values (e.g. GitHub Pages). Script checks records against the provider's published values. Reconciler Read
dangling-cname-subdomain-takeover CNAME target on a cloud provider is deprovisioned or unclaimed. Script resolves the CNAME chain and flags claimable targets. Diagnostic Read
dangling-cname-chain-intermediate-hop A multi-level CNAME chain has a claimable target partway through, not just at the end. Script follows the full chain, not only the first hop. Diagnostic Read
orphaned-records-after-teardown A or CNAME records remain pointing at decommissioned infrastructure with no owner. Script diffs zone records against a live infrastructure inventory. Reconciler Read
wildcard-pointing-at-deprovisioned-service A wildcard CNAME targets a third-party service that is gone, exposing every unclaimed subdomain to takeover. Script flags wildcards pointing at takeover-prone services. Diagnostic Read
rdap-hijack-signal-monitoring Registrant, nameserver, or status fields change unexpectedly ahead of an unauthorized transfer. Script polls RDAP and diffs fields over time. Diagnostic Read
caa-blocks-intended-ca CAA excludes the CA attempting issuance, causing an authorization error. Script queries CAA and cross-checks against the CA in use. Diagnostic Read
caa-blocks-wildcard-issuance CAA fails wildcard cert issuance even though the base domain issues fine. Script evaluates CAA at both apex and wildcard label. Diagnostic Read
caa-lookup-servfail-dnssec A CA's CAA check hits SERVFAIL from a broken DNSSEC chain, blocking renewal. Script validates DS, DNSKEY, and RRSIG before issuance. Diagnostic Read
tls-san-hostname-mismatch Served certificate's SAN list does not cover the requested hostname, causing handshake failures. Script opens a TLS connection and checks SAN against hostname. Diagnostic Read
tls-certificate-expiring Renewal automation fails silently and the certificate lapses. Script opens a TLS connection, reads notAfter, and alerts before expiry. Diagnostic Read
ds-record-mismatch-ksk-rollover Registrar's published DS no longer matches the zone's current KSK, breaking validation. Script compares DS at parent against DNSKEY at the zone. Diagnostic Read
stale-ds-records-orphaned Old DS records were never removed, so validators cannot build a trust chain. Script lists all DS records and flags ones with no matching key. Diagnostic Read
dnssec-pending-transfer-in The DS record never gets added automatically after a transfer, leaving DNSSEC perpetually pending. Script polls DS presence against expected state. Diagnostic Read
expired-rrsig-signatures A signing job stalls and RRSIG validity windows lapse, causing bogus or SERVFAIL answers. Script checks RRSIG expiration timestamps against current time. Diagnostic Read
spf-exceeds-lookup-limit Nested include mechanisms push SPF evaluation past 10 lookups, causing PermError. Script recursively counts lookups and flags overage. Diagnostic Read
duplicate-spf-records Two separate v=spf1 TXT records exist, which must be treated as PermError. Script queries TXT records and counts SPF-prefixed entries. Repair Read
spf-duplicate-all-mechanism Two all directives in one SPF record break evaluation order. Script parses the SPF record and flags duplicate or misordered mechanisms. Diagnostic Read
dkim-selector-missing The selector._domainkey record is absent or stale, so signatures cannot verify. Script queries expected selector names and flags absence. Diagnostic Read
dkim-cname-selector-not-published Some providers expect CNAME records for selectors and rotation stalls if missing. Script checks that both selectors resolve as CNAMEs to the provider's target. Reconciler Read
dkim-txt-record-malformed A copy-pasted or unsplit long key invalidates the public key value. Script fetches the TXT record and validates the key parses correctly. Diagnostic Read
dkim-key-stale-after-rotation DNS still publishes the old public key after a private key rotation, so signatures fail. Script diffs the deployed key against the published TXT. Reconciler Read
dmarc-record-missing-or-malformed The _dmarc TXT record is absent or missing required tags. Script fetches the record and validates syntax against DMARC tag grammar. Diagnostic Read
dmarc-stuck-at-p-none A domain never progresses past monitor-only policy, leaving it unprotected from spoofing. Script parses the DMARC record and flags p=none. Diagnostic Read
dmarc-rua-reports-not-arriving The rua destination lacks the required third-party authorization record on a different domain. Script checks both the DMARC record and the external auth TXT record. Diagnostic Read
leftover-mx-records-after-migration Old provider's MX entries remain after migration, splitting or losing mail. Script diffs the live MX set against the intended provider's documented hosts. Reconciler Read
mx-points-to-dead-host An MX target no longer accepts SMTP, silently dropping mail. Script resolves each MX host and probes port 25 connectivity. Repair Read
mx-target-missing-address-record The MX target hostname has no address record, so mail bounces. Script resolves each MX host and flags dangling targets. Diagnostic Read
mx-record-malformed-target An MX target includes a stray @ or is a bare IP instead of a hostname, violating RFC. Script validates MX target syntax and resolvability. Repair Read
ttl-too-high A long TTL keeps stale answers cached well after a record change. Script reads live TTL values and flags ones above a safe threshold before cutovers. Diagnostic Read
ttl-too-low A very short TTL multiplies query load on authoritative servers. Script estimates query volume from TTL and traffic to flag risky low values. Diagnostic Read
proxied-record-forces-ttl Enabling proxy mode forces TTL to automatic regardless of the value sent via API. Script detects TTL and proxy-status mismatches against intended config. Reconciler Read
resolver-answer-inconsistency A record's value differs between resolvers from stale caches or partial rollout. Script queries multiple public resolvers in parallel and diffs answers. Diagnostic Read
stale-negative-cache-nxdomain Resolvers cache a prior NXDOMAIN per the SOA negative TTL even after the record is added. Script queries multiple resolvers to detect stale negative caching. Diagnostic Read
domain-expiration-approaching RDAP or WHOIS expiration date falls inside a warning threshold with no renewal triggered. Script checks expiry on a schedule and alerts. Diagnostic Read
auto-renewal-payment-failure Auto-renew is on but billing failed silently, leaving the domain stuck in a grace period. Script polls RDAP status and flags domains stuck past renewal. Diagnostic Read
transfer-lock-blocking-renewal RDAP shows an approaching expiry plus a clientTransferProhibited lock blocking renewal or transfer. Script parses RDAP status codes and expiration together. Diagnostic Read
unowned-record-overwritten An automated DNS tool overwrites or silently reassigns a record it does not own, causing unpredictable drift. Script diffs intended versus live records before writing and checks ownership markers. Reconciler Read
duplicate-record-write-conflict Creating a record where one already exists at that name and type errors out. Script lists existing records before writing and upserts instead of blindly creating. Reconciler Read
stale-acme-challenge-record A leftover or already-deleted _acme-challenge TXT record leaves certificate renewal stuck in a retry loop. Script detects and clears stale challenge records past a timeout. Reconciler Read
api-token-missing-scope An API token lacks zone-read or zone-list permission, breaking automated record writes for certificate validation. Script pre-flight-checks token scopes before attempting writes. Diagnostic Read
zone-lookup-failure-for-subdomain Automation cannot auto-detect which hosted zone owns a subdomain, aborting a DNS-01 challenge. Script walks up the label tree to find the correct zone before writing. Diagnostic Read
false-positive-duplicate-detection Dedup logic misflags legitimate multivalue or weighted record sets as duplicates, blocking valid changes. Script replicates correct dedup logic using name, type, and set identifier. Reconciler Read

More fixes land as the guides are published. Watch or star the repo to follow along.

Running the tests

The decision logic in every fix is a pure function with no network calls, so the tests run anywhere.

# Python
pip install pytest
pytest

# Node
node --test

A note on safety

These scripts can change live DNS records through the Cloudflare API. Always run with DRY_RUN=true first, read the output, and confirm it is correct before you let a script write. Test against a non-production zone when you can.

Work with me

Fighting a DNS, email deliverability, or domain problem you would rather hand off? That is what I do.

License

MIT. Use it, change it, ship it.

About

Python and Node.js scripts that detect and repair automatable DNS and domain problems via the Cloudflare API. Guides: allanninal.dev/dns

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors