Documentation
Learn how to manage your DNS zones with DnsEditor
Getting Started
Requirements
- macOS 14.0+ or iOS 17.0+
- A DNS provider account or server:
- Cloudflare — API token with Zone:Edit permissions
- AWS Route 53 — IAM credentials with Route 53 access
- Google Cloud DNS — Service account with DNS Admin role
- BIND9 — Server with TSIG authentication configured
Adding a Provider
DnsEditor supports multiple DNS providers. To add a provider:
- Open Settings
- Tap Add Provider
- Select your provider type (Cloudflare, Route 53, Google Cloud DNS, or RFC2136/BIND9)
- Enter your credentials (see Providers for details)
- Add the zones you want to manage
You can add multiple providers and switch between them from the zone list.
Display Options
- Hide Auto-Generated DNSSEC — Hides RRSIG, NSEC, NSEC3, and NSEC3PARAM records. DS, CDS, CDNSKEY, and DNSKEY records are always shown (read-only).
- Clear Filters on Zone Change — Resets search text and record type filter when switching between zones.
- Reverse/Forward DNS Verification — Performs live DNS lookups to verify PTR consistency for A/AAAA records and forward consistency for PTR records. Results are displayed inline with color-coded indicators. Disable to skip the additional DNS queries.
- Sync to iCloud — Syncs your configuration and undo history across all your Apple devices.
Why hide DNSSEC records? RRSIG, NSEC, and NSEC3 records are automatically generated by your nameserver — they're not meant for humans to read or modify. RRSIG records contain cryptographic signatures that verify the authenticity of other records. NSEC/NSEC3 records provide authenticated denial of existence (proof that a name doesn't exist in the zone). For your own sanity, keep them hidden.
Supported Providers
DnsEditor supports four DNS providers. Choose the one that matches your infrastructure.
Cloudflare
Cloudflare offers a free DNS hosting tier with a powerful API. To connect DnsEditor to Cloudflare:
- Log in to the Cloudflare dashboard
- Go to My Profile → API Tokens
- Click Create Token
- Use the Edit zone DNS template, or create a custom token with:
- Permissions:
Zone → DNS → Edit - Zone Resources: Select the zones you want to manage
- Permissions:
- Copy the token and paste it into DnsEditor
Tip: Cloudflare's free tier includes unlimited DNS queries, making it ideal for testing and personal use.
AWS Route 53
Amazon Route 53 is AWS's scalable DNS service. To connect DnsEditor to Route 53:
- Log in to the AWS IAM Console
- Create a new IAM user or use an existing one
- Attach a policy with Route 53 permissions. Minimum required:
{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "route53:ListHostedZones", "route53:GetHostedZone", "route53:ListResourceRecordSets", "route53:ChangeResourceRecordSets" ], "Resource": "*" }] } - Generate an Access Key ID and Secret Access Key
- Enter these credentials in DnsEditor along with your AWS region (e.g., us-east-1)
Note: Route 53 does not have a free tier. Hosted zones cost $0.50/month plus query charges.
Google Cloud DNS
Google Cloud DNS is a scalable, reliable DNS service. To connect DnsEditor to Google Cloud DNS:
- Go to the Google Cloud Console → IAM → Service Accounts
- Create a new service account
- Grant the DNS Administrator role (or a custom role with
dns.changes.create,dns.resourceRecordSets.*,dns.managedZones.get) - Create a JSON key for the service account
- In DnsEditor, enter your Project ID and paste the JSON key contents
Note: Google Cloud DNS does not have a free tier, but new accounts receive $300 in credits.
RFC2136 (BIND9)
For self-hosted BIND9 servers, DnsEditor uses RFC2136 Dynamic DNS Updates with TSIG authentication:
- Enter your DNS server address (IP or hostname) and port (default: 53)
- Paste your TSIG key contents into the key field
The key should be in BIND format:
key "keyname" { algorithm hmac-sha256; secret "base64secret..."; };
After pasting the key, click Parse Key to validate. A green "Key Configured" indicator confirms success, showing the key name and algorithm.
See BIND9 Setup for detailed server configuration instructions.
BIND9 Server Setup
If you're using BIND9, DnsEditor can automatically fetch your zone list from a simple HTTP endpoint running on your nameserver. This is optional — you can always add zones manually.
Zone List Server
We provide a lightweight Python script that runs on your nameserver and returns a JSON list of your primary zones. The script queries BIND9's named-checkconf to enumerate zones.
Download the server files:
- zone_server.py — The zone list server script
- zone-server.service — Systemd service file
- install.sh — Installation script
Installation (Debian/Ubuntu)
- Download the server files to your nameserver:
mkdir -p /opt/zone-server && cd /opt/zone-server curl -O https://dnsedit.au/server/zone_server.py curl -O https://dnsedit.au/server/zone-server.service curl -O https://dnsedit.au/server/install.sh chmod +x install.sh zone_server.py
- Edit the service file to use HTTP (recommended):
nano zone-server.service
The default configuration uses HTTP on port 8053. This is the recommended setup since the zone list server is typically only used occasionally to populate your zone list.
- Run the installer:
sudo ./install.sh
- Verify the service is running:
curl http://your-nameserver.example.com:8053/zones
Manual Installation
If you prefer not to use the install script:
- Copy the script to
/usr/local/bin/:sudo cp zone_server.py /usr/local/bin/ sudo chmod +x /usr/local/bin/zone_server.py
- Copy the service file:
sudo cp zone-server.service /etc/systemd/system/
- Enable and start the service:
sudo systemctl daemon-reload sudo systemctl enable zone-server sudo systemctl start zone-server
Disable After Use
Since you'll likely only use the zone list server occasionally to populate your zone list, you can disable it after fetching your zones to avoid having the endpoint exposed:
sudo systemctl stop zone-server sudo systemctl disable zone-server
When you need to add new zones later, simply re-enable and start the service temporarily:
sudo systemctl enable zone-server sudo systemctl start zone-server
Your zone list is saved in DnsEditor, so you only need to run the server when adding new zones or refreshing the list.
HTTPS Configuration (Optional)
If you prefer to use HTTPS, the zone server supports Let's Encrypt certificates:
- Edit the service file and comment out the HTTP line
- Uncomment the HTTPS line and set your certificate path:
--cert-dir /etc/letsencrypt/live/nameserver.example.com
- Restart the service:
sudo systemctl restart zone-server
Using in DnsEditor
- Open DnsEditor Settings
- In the Zone List URL field, enter your server URL:
https://nameserver.example.com/
- Tap Fetch Zones to retrieve your zone list
The zones will appear in the "Configured Zones" list. You can still add or remove zones manually.
API Response Format
The zone server returns JSON in this format:
{
"forward": ["example.com", "example.org"],
"reverse": ["168.192.in-addr.arpa"]
}
If you have your own zone management system, you can implement this endpoint yourself.
TSIG Key Generation
DnsEditor authenticates with BIND9 using TSIG (Transaction Signature) keys. Generate a key on your nameserver using tsig-keygen:
tsig-keygen -a hmac-sha256 dnsedit-key
This outputs a key block you can paste directly into named.conf:
key "dnsedit-key" {
algorithm hmac-sha256;
secret "BASE64_SECRET_HERE";
};
Copy the entire key block (including the secret) — you'll need it in both named.conf and in DnsEditor's provider settings.
Zone Definition
Add a zone block to your named.conf (or an included file such as named.conf.local). This example shows a primary zone with TSIG authentication for dynamic updates and zone transfers:
zone "example.com" {
type master;
file "/var/cache/bind/example.com.db";
key-directory "/var/cache/bind/keys/example.com";
allow-update { key dnsedit-key; };
allow-query { any; };
allow-transfer {
key dnsedit-key; // DnsEditor
198.51.100.2; // secondary-ns1
203.0.113.5; // secondary-ns2
};
inline-signing yes;
dnssec-policy dnsedit;
};
Key points:
- allow-update — Lists the TSIG key(s) authorised to send DNS UPDATE requests. This is what DnsEditor uses to add, modify, and delete records.
- allow-transfer — Controls who can perform zone transfers (AXFR). Include the same TSIG key so DnsEditor can fetch the full zone, plus IP addresses of any secondary nameservers.
- key-directory — Where BIND stores the DNSSEC key files. You'll create this directory as part of the setup procedure below.
- inline-signing yes — BIND maintains a separate signed version of the zone automatically. Your zone file stays unsigned and human-readable.
- dnssec-policy — References the DNSSEC policy (see below). Remove this line and
inline-signingif you don't want DNSSEC.
DNSSEC Policy
Add a dnssec-policy block to named.conf (outside any zone block). This policy uses ECDSA P-256 keys with a KSK that never expires, so there is no need for parental agents or DS record rotation scripts:
dnssec-policy "dnsedit" {
dnskey-ttl 2d;
keys {
ksk lifetime unlimited algorithm ecdsap256sha256;
zsk lifetime 60d algorithm ecdsap256sha256;
};
max-zone-ttl 86400;
parent-ds-ttl 600;
parent-propagation-delay 2h;
publish-safety 2h;
retire-safety 2h;
purge-keys 90d;
signatures-refresh 15d;
signatures-validity 25d;
signatures-validity-dnskey 60d;
zone-propagation-delay 2h;
};
- ksk lifetime unlimited — The Key Signing Key never rolls over. Once you publish the DS record at your registrar, it stays valid indefinitely. This is the simplest approach and eliminates the need for parental agents or scripts to monitor KSK changes.
- zsk lifetime 60d — The Zone Signing Key rotates every 60 days. BIND handles this automatically — no manual intervention required.
- ecdsap256sha256 — ECDSA P-256 produces compact keys and signatures, keeping DNS responses small. It is widely supported by all major resolvers.
- signatures-validity 25d — Signatures are valid for 25 days and refreshed every 15 days, providing a 10-day window to recover from signing failures.
Why unlimited KSK lifetime? Rolling a KSK requires updating the DS record at your domain registrar — a process that varies by registrar and is often manual. With an unlimited KSK lifetime, you set the DS record once and never touch it again. The ZSK still rotates regularly, maintaining cryptographic freshness where it matters.
Recommended Setup Procedure
Here is a step-by-step procedure for adding a new DNSSEC-signed zone:
- Add the zone definition to
named.conf(ornamed.conf.local) with thednssec-policyandinline-signingdirectives as shown above. Make sure the zone file exists — even a minimal one with just an SOA and NS record is enough. - Create the key directory for the zone and set ownership so BIND can write the key files:
mkdir -p /var/cache/bind/keys/example.com chown bind:bind /var/cache/bind/keys/example.com
- Validate the configuration to catch any syntax errors:
named-checkconf
- Load the new zone — use
rndc reconfigureto pick up the new zone definition without disrupting existing zones:rndc reconfigure
BIND will load the zone, generate the initial KSK and ZSK, and begin signing automatically. You can verify the keys were created:ls /var/cache/bind/keys/example.com/
- Get the DS record from DnsEditor — open the zone in the app. The DNSKEY records will appear in the record list. Find the KSK (flag 257) and tap it to open QuickLook, then tap "Copy DS Record (SHA-256)".
- Publish the DS record at your domain registrar's DNSSEC settings. This establishes the chain of trust from the parent zone down to yours.
- Verify the chain — back in DnsEditor, tap the chain icon (🔗) in the zone toolbar to run DS Chain Validation. All links should show as valid.
With the unlimited KSK lifetime policy, this is a one-time setup. BIND handles ZSK rotation, re-signing, and all other DNSSEC maintenance in the background — you can add and edit records through DnsEditor without ever thinking about DNSSEC again.
Managing Zones
Zone List Toolbar
The toolbar above the zone list provides quick access to zone management:
- + — Add a new zone manually
- ↻ — Refresh the zone list
- ⧉ — Toggle the sidebar view
Zone List
The zone list displays all configured zones, organized into forward zones and reverse zones. Each zone shows its serial number and record count. A green checkmark indicates the zone loaded successfully.
- Select Zone — Click a zone to fetch and display its records
- Remove Zone — Swipe left or right-click to remove a zone from the list
Zone Hierarchy
Parent zones with subdomains display a disclosure chevron. Click to expand and reveal child zones indented beneath the parent. In the screenshot, a02.au contains two subdomains: test.a02.au and unsigned.a02.au.
Record List Toolbar
The toolbar above the record list provides these controls:
- Zone name — Shows the current zone with a lock icon and "DNSSEC signed" badge for signed zones
- + — Add a new DNS record
- Filter (⊖▾) — Filter records by type (A, AAAA, MX, etc.)
- Refresh (↻) — Reload the zone from the DNS server
- Zone Scanners — Scan all hosts for TLSA or SSHFP records (see Zone Scanners)
- Chain (🔗) — Validate DNSSEC DS chain (only shown for signed zones)
- Search (🔍) — Search records by name or value
iOS: On iPhone and iPad, less frequently used tools (refresh, undo history, zone scanners, DS chain validation) are grouped in the overflow menu (⋯) to keep the toolbar clean.
Working with Records
Viewing Records
Records are displayed with their name, type, value, and TTL. Use the filter menu to show specific record types, or search to find records by name or value. Click a record type below for details:
Provider Compatibility
Not all DNS providers support every record type. DnsEditor automatically shows only the types available for your active provider. The table below shows which editable record types are supported by each provider:
| Record Type | BIND9 | Cloudflare | Route 53 | Google Cloud |
|---|---|---|---|---|
| A | ✓ | ✓ | ✓ | ✓ |
| AAAA | ✓ | ✓ | ✓ | ✓ |
| CAA | ✓ | ✓ | ✓ | ✓ |
| CNAME | ✓ | ✓ | ✓ | ✓ |
| DNAME | ✓ | — | — | — |
| DS | ✓ | ✓ | ✓ | ✓ |
| HINFO | ✓ | — | — | — |
| HTTPS | ✓ | ✓ | ✓ | ✓ |
| LOC | ✓ | ✓ | — | — |
| MX | ✓ | ✓ | ✓ | ✓ |
| NAPTR | ✓ | ✓ | ✓ | ✓ |
| NS | ✓ | ✓ | ✓ | ✓ |
| PTR | ✓ | ✓ | ✓ | ✓ |
| RP | ✓ | — | — | — |
| SRV | ✓ | ✓ | ✓ | ✓ |
| SSHFP | ✓ | ✓ | ✓ | ✓ |
| SVCB | ✓ | ✓ | ✓ | ✓ |
| TLSA | ✓ | ✓ | ✓ | ✓ |
| TXT | ✓ | ✓ | ✓ | ✓ |
BIND9 (RFC2136) supports all record types. DNAME, HINFO, and RP are only available with BIND9. LOC records are supported by BIND9 and Cloudflare.
Adding Records
- Tap the + button in the zone detail view
- Select the record type
- Enter the record name (use @ for the zone apex)
- Fill in the type-specific fields
- Set the TTL (time-to-live in seconds)
- Tap Save to push the change to your DNS server
Editing Records
Tap any record to open the editor. Modify the fields as needed and save. The original record is deleted and replaced with the updated version via DNS UPDATE.
SOA records and DNSSEC records (DNSKEY, RRSIG, NSEC) are read-only and cannot be edited directly.
Deleting Records
- Single record — Swipe left or use the context menu
- Multiple records — Enter selection mode, select records, then tap Delete
Deleted records can be restored from the Undo History.
Reverse/Forward DNS Verification
How It Works
When enabled in Settings, DnsEditor performs live DNS lookups for every A, AAAA, and PTR record in the zone and displays the result inline next to the record value:
- Green — The reverse (or forward) lookup matches. An A/AAAA record's PTR points back to the same hostname, or a PTR record's forward A/AAAA resolves to the same IP.
- Red — A record exists but points elsewhere. The PTR for an A record resolves to a different hostname, or the forward record for a PTR resolves to a different IP.
- Orange — No matching record was found. Shown as "(no PTR)" for A/AAAA records, or as an orange IP for PTR records with no forward entry.
Results are cached for the duration of your session, so scrolling through large zones stays fast.
Private Networks (RFC 1918)
Public DNS resolvers cannot resolve reverse lookups for private IP ranges like 192.168.x.x, 10.x.x.x, or 172.16–31.x.x. When the app detects that a reverse or forward zone for a given IP is managed by one of your BIND9 (RFC 2136) providers, it queries that provider's nameserver directly instead of using public resolvers. This means verification works correctly for both public and private networks.
Fix Missing Records
When an A/AAAA record has no PTR, or a PTR record has no matching forward entry, a Fix button appears — but only if the target zone is managed by the app. Tapping Fix creates the missing record in the correct zone automatically:
- A/AAAA with no PTR — Creates a PTR record in the matching reverse zone (e.g., in-addr.arpa or ip6.arpa), pointing back to this hostname.
- PTR with no forward — Creates an A or AAAA record in the matching forward zone with the derived IP address.
The record is added through the provider that manages the target zone, even if it is a different provider than the one you are currently viewing.
Paired Deletion
When you delete an A, AAAA, or PTR record that has a confirmed bidirectional match (shown in green), the delete confirmation offers a Delete Both option. This removes the counterpart record from the other zone at the same time — for example, deleting an A record and its matching PTR, or a PTR and its matching A record. The option only appears when both records agree with each other (the match is green in both directions) and the other zone is managed by the app.
Toggling the Feature
Go to Settings → Display and toggle Reverse/Forward DNS Verification. When disabled, no additional DNS lookups are performed, no color-coded indicators are shown, and Fix buttons and paired deletion are hidden.
DNSSEC Support
Signed Zones
Zones signed with DNSSEC display an indicator in the toolbar showing a lock icon and "DNSSEC signed" badge. DnsEditor automatically detects signed zones by the presence of DNSKEY or RRSIG records.
For zones hosted on cloud providers (Cloudflare, Route 53, Google Cloud DNS), DnsEditor queries public DNS to detect DNSSEC status, ensuring the DNSSEC badge displays correctly even when provider APIs don't return DNSKEY records.
DS Chain Validation
For DNSSEC-signed zones, tap the chain icon (🔗) to validate the DS record chain from your zone up to the root. This verifies that your zone's delegation signer records are correctly published in the parent zone.
The validation dialog shows:
- Chain Status — Overall validation result (e.g., "Full Chain Valid - 2 of 2 links valid")
- SOA Signing Key — Which DNSKEY (by key tag) signs the zone's SOA record, its algorithm, and signature validity window. If the signer is a ZSK, the KSK(s) that signed the DNSKEY RRset are also shown, displaying the full trust path from DS through KSK to ZSK
- KSK Rollover Detection — Alerts when CDS records differ from published DS records, indicating a key rollover is in progress. A separate "New KSK Published" indicator appears when a KSK exists in the DNSKEY set but has no matching DS in the parent zone — catching the earliest phase of a rollover
- Link Details — Each delegation link (e.g., test.a02.au → a02.au → au) with key tags, algorithm info, and TTL values for DS, CDS, DNSKEY, and CDNSKEY records
- Key Validation — Individual key status showing algorithm (e.g., ECDSA P-256/SHA-256) and validity
Read-Only DNSSEC Records
DNSSEC operational records are protected from editing:
- DNSKEY — Zone signing keys
- RRSIG — Record signatures
- NSEC/NSEC3 — Authenticated denial of existence
You can still manage DS, TLSA, and SSHFP records which are used for trust anchors and certificate pinning.
QuickLook Preview
QuickLook lets you quickly browse through records without opening the full editor. It's available for all records via the context menu and for read-only records (DNSSEC) via tap or click.
Opening QuickLook
- macOS — Select a record and press Space, or right-click and choose "View"
- iPad — Select a record and press Space on an external keyboard, or long press and choose "View"
- iPhone — Long press a record and choose "View", or tap a read-only record
Navigating Records
While QuickLook is open, you can move between records without closing and reopening:
- Arrow buttons — Use the up/down chevron buttons in the QuickLook toolbar (all platforms)
- Keyboard — Press ↑ and ↓ arrow keys (macOS and iPad with external keyboard)
The record list scrolls automatically to keep the selected record visible.
Closing QuickLook
- macOS — Press Space or Escape, or close the panel
- iPad — Press Space or Escape, or tap "Done"
- iPhone — Tap "Done" or swipe down
DS Record Generation
When viewing a KSK (Key Signing Key) DNSKEY record in QuickLook, a "Copy DS Record (SHA-256)" button appears. This computes the DS digest from the DNSKEY and copies it to your clipboard in standard format:
keyTag algorithm digestType HEXDIGEST
Paste this directly into your domain registrar's DNSSEC settings to establish the chain of trust for your zone.
Zone Scanners
Zone scanners automatically scan all A/AAAA hosts in your zone and generate or update security records. Access them from the toolbar: on macOS via the shield menu, on iOS via the overflow menu (⋯).
TLSA Scanner
The TLSA scanner connects to each host, fetches the TLS certificate, and computes DANE-EE (3 1 1) TLSA records using the SPKI SHA-256 hash. A port picker in the toolbar lets you select the target port: 443 (HTTPS), 25 (SMTP), 587 (Submission), 465 (SMTPS), 143 (IMAP), 993 (IMAPS), 110 (POP3), or 995 (POP3S). TLSA record names use the selected port prefix (e.g. _25._tcp. for SMTP).
For STARTTLS ports (25, 587, 143, 110), the scanner performs the protocol-specific plaintext handshake (SMTP EHLO/STARTTLS, IMAP STARTTLS, or POP3 STLS) before upgrading to TLS to fetch the certificate. Direct TLS ports (443, 465, 993, 995) connect with TLS immediately.
Results are categorized as:
- Add — New TLSA records for hosts without existing records
- Update — Existing TLSA records where the certificate hash has changed
- Unchanged — Existing TLSA records that match the current certificate
- Unreachable — Hosts that did not respond on the selected port
The scanner also checks Subject Alternative Names (SANs) and warns if the hostname is not covered by the certificate. Review the results and use the checkboxes to select which changes to apply.
SSHFP Scanner
The SSHFP scanner connects to port 22 on each host, fetches all SSH host keys, and computes both SHA-1 and SHA-256 fingerprints for each key type. Results include:
- Add — New SSHFP records for hosts or key types not yet in DNS
- Fingerprint Changed — Existing SSHFP records where the fingerprint differs from the scanned key. These are highlighted in red with a man-in-the-middle warning. You must explicitly confirm the key change is intentional before the change can be selected for application
- Remove Orphaned — SSHFP records for hostnames that no longer have A/AAAA records in the zone
- Unchanged — Existing SSHFP records that match the current host keys
- Unreachable — Hosts that did not respond on port 22
Using the Scanners
- Open a zone and tap the scanner button (shield icon on macOS, or via the ⋯ menu on iOS)
- Select "Scan TLSA Records" or "Scan SSHFP Records"
- Wait for the scan to complete — progress is shown for each host
- Review the results. Use the checkboxes to select or deselect individual changes
- Tap Apply to push the selected changes to your DNS server
Note: Wildcard records (*.example.com) are skipped during scanning. If both A and AAAA records exist for the same hostname, the host is scanned only once.
Zone Sanity Check
The Zone Sanity Check verifies that all your public authoritative nameservers are serving identical zone data. It queries each nameserver directly using non-recursive queries (RD=0) to test what each server actually serves, rather than what it can resolve via recursion.
Running a Sanity Check
- Open a zone in the record list
- On macOS, click the shield menu ("Zone Scanners") in the toolbar and select "Zone Sanity Check"
- On iOS, tap the overflow menu (⋯) and select "Zone Sanity Check"
- The check runs automatically when the sheet opens. A progress indicator shows the current stage
- When complete, results are displayed in a sectioned list
What It Checks
The sanity check performs three verifications against every nameserver listed in the zone's apex NS records:
- NS Delegation — Queries the parent zone's authoritative nameservers for the child zone's NS delegation and compares with the NS records in the zone itself. A mismatch means the parent zone and your zone disagree about which nameservers are authoritative.
- SOA Consistency — Queries the SOA record from each nameserver directly and compares serial numbers. Mismatched serials indicate a nameserver has not received the latest zone transfer.
- Record Parity — For every unique (name, type) pair in the zone, queries each nameserver and compares the returned values with the zone data. DNSSEC auto-generated records (RRSIG, NSEC, NSEC3, NSEC3PARAM, DNSKEY, CDNSKEY, DS, CDS) and SOA records are excluded from comparison since they may legitimately differ between servers.
Understanding Results
- NS Delegation — A green checkmark means the parent and zone NS records match. An orange warning lists nameservers that appear only in the parent or only in the zone.
- SOA Consistency — Each nameserver is listed with its serial number. Green means it matches the expected serial; red indicates a mismatch or unreachable server.
- Record Differences — If differences are found, they are grouped by record (name and type). Each row shows the record value and which nameservers are affected. Records are categorised as:
- Missing (red) — The record exists in the zone but is not served by the listed nameservers
- Extra (orange) — The nameservers return a record that is not in the zone
- Value differs (yellow) — The record exists on both sides but with different values
- All Records Consistent — A green checkmark confirms all nameservers serve identical records.
TCP Fallback
DNS queries over UDP are limited in response size. When a response is truncated (TC bit set), the sanity check automatically retries the query over TCP to get the complete response. This is important for records with large values, such as DKIM TXT records that can exceed 512 bytes.
Exporting Results
After a check completes, tap the share button in the toolbar to export the results as a plain-text report. The report includes:
- Zone name and check date
- NS delegation status
- SOA serial for each nameserver
- All record differences with affected nameservers
Use this to save a record of zone health, share with colleagues, or track issues over time.
Tips
- The check refreshes the zone from your DNS server before running, so results always reflect the latest zone data
- If a nameserver is unreachable, it is reported in the SOA section and its records are not compared
- IPv6 addresses are normalised to canonical form before comparison, so equivalent representations (e.g.,
::1vs0:0:0:0:0:0:0:1) are correctly identified as matching - Use the refresh button to re-run the check after making changes to your zone
Zone Cleanup
The Zone Cleanup tool scans your zone to identify and fix forward/reverse DNS mapping inconsistencies across all your managed reverse zones. It detects dangling PTR records (PTRs without corresponding A/AAAA records), missing PTR records, and incorrect mappings where the forward and reverse records don't match.
Opening Zone Cleanup
- Open a zone in the record list (typically a forward zone like
example.com) - On macOS, click the shield menu ("Zone Scanners") in the toolbar and select "Zone Cleanup"
- On iOS, tap the overflow menu (⋯) and select "Zone Cleanup"
- The scan runs automatically when the sheet opens and checks all A/AAAA records in the zone against their reverse mappings
What It Checks
Zone Cleanup performs two types of scans:
- Forward Mapping Issues — For each A/AAAA record in your zone, the tool checks if a matching PTR record exists in the appropriate reverse zone. Issues include:
- Missing PTR — The A/AAAA record exists but there's no corresponding PTR record
- Incorrect PTR — A PTR record exists but points to the wrong hostname
- Circular Reference — Both hostnames point to the same IP (informational only)
- Reverse Mapping Issues — Scans all managed reverse zones for PTR records that point to hostnames in the current zone. Issues include:
- Dangling PTR — A PTR record points to a hostname that has no A/AAAA record in the forward zone
Note: The scan only checks reverse zones that are managed by the same provider and listed in your zone configuration.
Viewing Results
Results are split into two tabs: Forward Issues and Reverse Issues. Each issue shows:
- Issue type with a color-coded severity badge (High for missing/incorrect, Medium for dangling)
- Hostname and IP address
- Current PTR value (if it exists) and expected PTR value
- Reverse zone location (for dangling PTRs)
- Fix buttons for actionable issues
Fixing Issues
For most issues, you can fix them directly from the cleanup view:
- Missing PTR — Tap "Fix Issue" to create the PTR record in the correct reverse zone
- Incorrect PTR — Tap "Fix Issue" to update the PTR to point to the correct hostname
- Dangling PTR — Choose between:
- Delete PTR — Remove the dangling PTR record from the reverse zone
- Add A/AAAA — Create the missing forward record in the current zone
After applying fixes, the scan automatically reruns to refresh the results.
Bulk Delete Dangling PTRs
When multiple dangling PTR records are detected, a "Delete All Dangling PTR Records" button appears in the Reverse Issues tab. This operation:
- Deletes all dangling PTRs in a single optimized batch operation
- Groups deletions by reverse zone for efficiency
- Creates a single consolidated undo entry for all deletions (not separate entries per zone)
- Works across multiple reverse zones, including IPv6 zones
The bulk delete is much faster than deleting records individually, reloading each zone only once instead of after every deletion.
Undo Support
All fixes and deletions are tracked in the undo history. Bulk operations create a single undo entry labeled "Multiple Reverse Zones (N)" if records span multiple zones. To view what's in a bulk operation:
- Open the undo history (toolbar → overflow menu → "Undo History")
- Tap the disclosure chevron on the bulk delete entry to expand it inline and see all records
- Alternatively, right-click (or long-press on iOS) and select "View Records" for a full-screen detail view
When restoring a bulk deletion, records are automatically restored to their correct zones, even across multiple IPv4 and IPv6 reverse zones.
Export Report
Tap the "Export Report" button to generate a plain-text summary of all issues found. The report includes:
- Zone name and scan date
- Total issue count
- Detailed list of forward issues (missing/incorrect PTRs)
- Detailed list of reverse issues (dangling PTRs)
- Reverse zone locations and severity levels
Use the report for documentation, sharing with team members, or tracking cleanup progress.
Tips
- Run Zone Cleanup regularly to keep forward and reverse DNS synchronized
- Use the bulk delete feature for large-scale cleanups to save time
- The scan automatically excludes reverse zones that are not managed by your provider
- For non-routable networks (RFC 1918), the scan queries your BIND9 provider's nameserver directly
- Use the export feature to create an audit trail before making bulk changes
DS Update Scanner
The DS Update Scanner detects KSK (Key Signing Key) rollovers across all zones in a BIND9 provider. When BIND9's dnssec-policy rotates a KSK, it publishes CDS records that differ from the parent zone's DS records, signalling that the parent needs to be updated. This scanner automates the detection of that state.
BIND9 only: The DS Update Scanner is only available for RFC 2136 (BIND9) providers. Cloud providers (Cloudflare, Route 53, Google Cloud DNS) manage DNSSEC internally and do not require manual DS updates.
Opening the Scanner
The DS Update Scanner lives in the zone list toolbar (not the zone detail toolbar) because it operates across all zones in the provider:
- On macOS and iOS, click the rotation icon (↺) in the zone list toolbar
The button only appears when the active provider is RFC 2136 (BIND9).
Pre-Scan Configuration
Before scanning, a configuration screen lets you choose which zones to include:
- TLD quick-exclude — At the top, detected TLDs are listed with "Exclude" buttons. Some TLDs (e.g., .cz, .se, .ch, .nu) support automated CDS/CDNSKEY scanning per RFC 7344/8078, meaning DS updates happen automatically at the registry. These TLDs are excluded by default on first use. Reverse zones (in-addr.arpa, ip6.arpa) are also listed for quick exclusion.
- Per-zone toggles — Below the TLD buttons, each zone has a checkbox. Zones under auto-CDS TLDs are labelled "(auto-CDS)" for reference.
- Persistence — Your exclusion choices are saved per provider, so you only need to configure them once.
Tap Start Scan in the toolbar to begin scanning the selected zones.
Understanding Results
After scanning, zones are grouped into sections:
- DS Update Needed — Zones where the CDS records differ from the parent DS records, indicating a KSK rollover is in progress. The current DS and new CDS key tags and algorithms are shown. These zones need their DS records updated at the registrar (or parent zone).
- Up to Date — Zones where DS matches CDS, or no CDS is published. No action needed.
- Not DNSSEC Signed — Zones with no DS record in the parent zone.
- Excluded (Auto-CDS TLDs) — Zones that were skipped because they are under a TLD that handles CDS updates automatically.
- Errors — Zones where the DNS query failed (timeout, server error, etc.).
Direct DS Updates
If a zone's parent is also managed by the same BIND9 provider (e.g., test.a02.au under a02.au), the scanner shows an "Update DS in [parent]" button. This applies the DS change directly via RFC 2136 Dynamic DNS Update.
The update uses a safe two-phase approach to maintain the chain of trust:
- Phase 1: Add the new DS record (from CDS) to the parent zone
- Phase 2: Remove the old DS record(s) from the parent zone
If phase 1 succeeds but phase 2 fails, the chain of trust remains intact (both old and new DS are valid). An error message will instruct you to manually remove the old DS record so the KSK rollover can complete.
For zones whose parent is a public TLD (e.g., .com, .au), you will need to update the DS record at your domain registrar manually. The report shows the new DS data to enter.
Exporting the Report
When zones need DS updates, a share button appears in the toolbar. The plain-text report includes:
- Provider name and scan date
- Summary (zones scanned, signed, needing updates)
- Current DS and new CDS for each zone needing an update
- Lists of up-to-date, unsigned, excluded, and errored zones
- Zones updated directly are marked with
[UPDATED]
When to Use
Run the DS Update Scanner periodically or after initiating a KSK rollover. If you use a DNSSEC policy with ksk lifetime unlimited, you will never need this scanner since the KSK never rotates. It is useful when:
- You use a DNSSEC policy with a finite KSK lifetime
- You manually initiate a KSK rollover with
rndc dnssec -rollover -key <id> <zone> - You want to verify that all DS records are current across your infrastructure
Timing: After initiating a KSK rollover, BIND9 takes several hours (depending on your DNSSEC policy timers) before publishing the new CDS record. Run the scanner after the CDS has been updated — check your zone's CDS records to confirm.
Background Scanning
Instead of manually running the DS Update Scanner, you can enable automatic background scanning for each BIND9 provider. When enabled, the app periodically checks all included zones for KSK rollovers and sends a local notification if DS updates are needed.
To enable background scanning:
- Open Settings and edit your BIND9 provider
- In the Background DS Scanning section, toggle on Automatic DS Scanning
- Choose the check interval — Daily or Weekly
- Grant notification permission when prompted
When the scan detects zones needing DS updates:
- A local notification is posted with the zone names or count
- A red warning indicator appears in the zone list sidebar
- Tapping the notification or the red indicator opens the scan results directly — no need to re-run the scan
While a background scan is in progress, a spinning indicator with "Checking DS records..." appears at the bottom of the zone list. The indicator clears automatically when the scan completes without finding issues, or turns red if updates are needed.
Platform details: On iOS/iPadOS, background scanning uses BGAppRefreshTask which runs periodically when the system allows. On macOS, it uses NSBackgroundActivityScheduler which runs while the app is open. An immediate scan also runs each time the app launches.
SSHFP Client Setup
Once you have SSHFP records published in a DNSSEC-signed zone, you can configure OpenSSH to verify host keys via DNS instead of relying on the ~/.ssh/known_hosts file. This eliminates "trust on first use" prompts and detects host key changes through DNSSEC validation.
Enable DNS Verification (All Hosts)
Create a global SSH config snippet that enables SSHFP lookups for every host you connect to. On macOS, drop-in config files go in /etc/ssh/ssh_config.d/:
# /etc/ssh/ssh_config.d/10-dns-verify.conf
# Enable DNSSEC-based SSHFP host key verification
Host *
VerifyHostKeyDNS yes
With this setting, OpenSSH will look up SSHFP records for every host you connect to. If a matching DNSSEC-validated record is found, the host key is accepted automatically. If no SSHFP record exists or DNSSEC validation fails, SSH falls back to normal known_hosts behaviour — so this is safe to enable globally.
Skip known_hosts for Your Domains
For domains you control and have fully deployed SSHFP records on, you can go a step further and disable known_hosts entirely. This means DNSSEC becomes the sole source of trust for host key verification — there is no stale known_hosts entry to conflict when you rotate keys or rebuild a server:
# /etc/ssh/ssh_config.d/90-owned-domains.conf
# Domains with SSHFP records: trust DNS, skip known_hosts
Host *.example.com *.example.org
VerifyHostKeyDNS yes
StrictHostKeyChecking yes
UserKnownHostsFile /dev/null
GlobalKnownHostsFile /dev/null
Replace the host patterns with your own domains. You can list multiple patterns separated by spaces.
- VerifyHostKeyDNS yes — Look up SSHFP records in DNS and verify via DNSSEC
- StrictHostKeyChecking yes — Reject the connection if the host key does not match (no interactive prompt)
- UserKnownHostsFile /dev/null — Do not read or write the per-user known_hosts file
- GlobalKnownHostsFile /dev/null — Do not read the system-wide known_hosts file
Important: Only use this configuration for domains where every SSH host has SSHFP records published in a DNSSEC-signed zone. If SSHFP records are missing or the zone is not signed, connections to those hosts will be rejected.
Prerequisites
- Your zone must be DNSSEC-signed — SSHFP records without DNSSEC offer no security benefit, and OpenSSH will only trust DNSSEC-validated responses
- Your local DNS resolver must support DNSSEC validation (e.g., Unbound, systemd-resolved with DNSSEC=yes, or a validating forwarder like Cloudflare 1.1.1.1 or Google 8.8.8.8)
- SSHFP records must be published for all key types offered by the server — use the SSHFP Scanner in DnsEditor to generate them automatically
- macOS users: You must install OpenSSH from Homebrew (see the known issue below)
macOS Known Issue
The version of OpenSSH bundled with macOS does not perform DNSSEC validation, even when your DNS resolver supports it. When VerifyHostKeyDNS is set to yes, Apple's SSH will find SSHFP records in DNS but treat them as unverified — it will prompt you to confirm the fingerprint manually rather than accepting it automatically. This defeats the purpose of SSHFP.
The workaround is to install OpenSSH via Homebrew, which builds against a DNS library that performs proper DNSSEC validation:
brew install openssh
After installation, Homebrew's ssh is placed in /opt/homebrew/bin/ssh (Apple Silicon) or /usr/local/bin/ssh (Intel). Make sure this path appears before /usr/bin in your $PATH, or invoke it explicitly:
# Verify you're using Homebrew's version which ssh # should show /opt/homebrew/bin/ssh ssh -V # should show a newer version than Apple's
Homebrew's OpenSSH uses its own config file at /opt/homebrew/etc/ssh/ssh_config and does not read the system drop-in directory by default. To pick up the config files described above, add an Include directive at the top of Homebrew's config:
# /opt/homebrew/etc/ssh/ssh_config — add this line at the top Include /etc/ssh/ssh_config.d/*.conf
How to tell: Run ssh -v server.example.com and look at the fingerprint line. Apple's SSH will say "found 6 insecure fingerprints in DNS" and reject the connection. Homebrew's SSH will say "found 6 secure fingerprints in DNS" and connect successfully.
Verifying It Works
Connect with verbose output to confirm SSHFP verification:
ssh -v server.example.com 2>&1 | grep -i dns
A working setup (Homebrew's OpenSSH) will show:
debug1: found 6 secure fingerprints in DNS debug1: verify_host_key_dns: matched SSHFP type 4 fptype 1 debug1: verify_host_key_dns: matched SSHFP type 4 fptype 2 debug1: matching host key fingerprint found in DNS
A broken setup (Apple's built-in SSH) will show insecure instead of secure and fail with "Host key verification failed":
debug1: found 6 insecure fingerprints in DNS debug1: verify_host_key_dns: matched SSHFP type 4 fptype 1 debug1: verify_host_key_dns: matched SSHFP type 4 fptype 2 debug1: matching host key fingerprint found in DNS No ED25519 host key is known for server.example.com and you have requested strict checking. Host key verification failed.
If you see "No matching host key found in DNS", check that the SSHFP records are published and your resolver validates DNSSEC.
Features
Internationalized Domain Names (IDN)
DnsEditor fully supports Internationalized Domain Names with automatic Punycode encoding and decoding:
- Unicode display — Punycode domains like "xn--hsteng-bya.no" are displayed as "høsteng.no" throughout the interface
- Automatic encoding — Enter domain names in your native language; DnsEditor automatically encodes them to Punycode for DNS operations
- Copy Punycode — The record editor shows the encoded DNS name for easy copy/paste into configuration files like named.conf
- Proper sorting — Zones and records are sorted by their Unicode names, not their Punycode representation
- Unicode search — Search works with both Unicode characters and Punycode strings
Example: Add a zone "høsteng.no" or "xn--hsteng-bya.no" — both will display as "høsteng.no" and work identically. When editing records, the Punycode version is shown below the input field for reference.
Undo History
Every record deletion and modification is logged to the undo history. Access it from the toolbar to review and restore accidentally deleted or changed records. Bulk operations (such as zone cleanup) create a single consolidated entry that can be expanded inline to see all individual records.
Bulk Operations
Select multiple records for batch deletion. On iOS, tap Select to enter edit mode. On macOS, use Command-click or Shift-click.
Search and Filter
Find records by name or value using search. Filter by record type using the filter menu. Filters can be combined.
Cross-Platform
DnsEditor runs natively on macOS and iOS with a consistent interface. Your settings sync across devices via iCloud.
Troubleshooting
General
Records Not Loading
- Ensure the zone name is correct and exists on the provider
- Try refreshing the zone using the reload button in the toolbar
- Check for network connectivity issues
- Verify your credentials have not expired or been revoked
Cloudflare
Authentication Failed
- Verify your API token is correct and has not expired
- Ensure the token has
Zone → DNS → Editpermissions - Check that the token's zone resources include the zones you want to manage
- If using a restricted token, ensure it covers all required zones
Cloudflare Update Errors
- Cloudflare does not allow CNAME records at the zone apex unless "CNAME Flattening" is enabled
- Proxied records (orange cloud) may have restrictions on TTL values
- Some record types (e.g., SOA, NS at apex) are managed by Cloudflare and cannot be modified via the API
AWS Route 53
Access Denied
- Verify your Access Key ID and Secret Access Key are correct
- Ensure the IAM user/role has the required Route 53 permissions (
route53:ListHostedZones,route53:ListResourceRecordSets,route53:ChangeResourceRecordSets) - Check the AWS region setting matches your account configuration
- If using temporary credentials (STS), ensure they have not expired
Route 53 Update Errors
- Route 53 requires record changes to be submitted as change batches — DnsEditor handles this automatically, but conflicts can occur if the zone was modified externally between loading and saving
- Alias records are specific to Route 53 and may not appear as expected when viewed as standard DNS records
- NS and SOA records at the zone apex cannot be deleted
- If you get a "PriorRequestNotComplete" error, wait a moment and try again — Route 53 processes changes sequentially
Google Cloud DNS
Permission Denied
- Verify the Project ID matches the project containing your DNS zones
- Ensure the service account JSON key is complete and valid (it should start with
{"type": "service_account") - Check that the service account has the DNS Administrator role or equivalent custom permissions
- The Cloud DNS API must be enabled in your Google Cloud project
Google Cloud DNS Update Errors
- Google Cloud DNS uses a Changes API that requires specifying both the old and new record values — if the zone was modified externally, reload the zone before making changes
- Record sets with the same name and type are grouped — adding a duplicate may result in an error
- SOA and NS records at the zone apex are managed by Google and have restrictions on modification
RFC2136 (BIND9)
Connection Failed
- Verify the DNS server address and port (default: 53) are correct
- Check that the DNS port is accessible from your network (not blocked by a firewall)
- Ensure your TSIG key name and secret match the server's
named.confconfiguration exactly - Confirm the TSIG algorithm matches (HMAC-SHA256 is recommended)
Zone Not Loading
- DnsEditor loads zones via AXFR (zone transfer). If a zone appears in the list but fails to load its records, check that
allow-transferinnamed.confincludes your TSIG key:zone "example.com" { type master; allow-transfer { key "keyname"; }; allow-update { key "keyname"; }; }; - Without the TSIG key in
allow-transfer, BIND9 will silently refuse the zone transfer and DnsEditor will show an empty or failed zone - If you have secondary nameservers, list both the TSIG key and the secondary IPs in
allow-transfer
Update Refused
- Verify your TSIG key has update permissions for the zone
- Check the BIND9
allow-updatedirective includes your TSIG key:zone "example.com" { type master; allow-update { key "keyname"; }; }; - Some record types (SOA, DNSSEC operational records) may be restricted by server policy
- If the server log shows "update denied", check the BIND9 logs for the specific reason:
journalctl -u named
TSIG Key Issues
- The key must be in BIND format:
key "keyname" { algorithm hmac-sha256; secret "base64..."; }; - Ensure there are no extra whitespace or line break issues when pasting the key
- After pasting, click "Parse Key" to validate — a green indicator confirms the key was parsed successfully
- The key name in DnsEditor must match the key name configured on the server exactly (case-sensitive)
Concurrent Update Errors
Starting in version 2.4.0, DnsEditor adds RFC 2136 prerequisites to every update and delete operation. These prerequisites verify that the record on the server still matches what was loaded in the app before applying the change. If the record was modified or deleted by another client (e.g., DHCPD, an ACME client, or another DNS editor), the server rejects the update atomically.
- "Record was modified or deleted by another client" — The record you are editing or deleting has changed on the server since the zone was loaded. Reload the zone and try again.
- "A conflicting record already exists" — A prerequisite check for record absence failed because a matching record already exists. This is less common and typically indicates a race condition with another client creating the same record.
- Both errors are safe — no partial changes are applied. The server evaluates prerequisites while holding the zone lock, so the zone is never left in an inconsistent state.
- For bulk delete operations (e.g., zone cleanup "Delete All"), individual records are sent as separate updates through the provider. If one record was changed, only that specific delete fails — other records in the batch may still succeed.
Debug Logging
DnsEditor includes a debug logging system that records DNS wire data, decision points, and key events to a log file. This is available on all platforms (iOS, iPadOS, and macOS) and is useful for diagnosing update failures, prerequisite rejections, and TSIG authentication issues.
- Enable debug logging in the app: open Settings and toggle Write debug log to file under Debug Logging
- Optionally enable Obfuscate hostnames in logs to replace real hostnames with hashed values before sharing
- Use Configure Categories to select which log categories to record — enable only what you need to keep log files focused
- Use Manage Log Files to view, share, reveal in Finder, or delete log files
- Logs include wire-level DNS UPDATE messages, prerequisite sections, server response codes, and TSIG signing details
- When reporting an issue, attach the debug log — it contains all the information needed to diagnose the problem