Introduction
DNSSEC is one of those pieces of infrastructure that sounds complicated right up until you do it once. It is cryptographic signing for your DNS zone, so that when someone looks up your domain, their resolver can verify the answer actually came from you and wasn’t forged somewhere along the way. Without it, DNS runs on trust — every cache, every ISP resolver, every hotel Wi-Fi network between you and the authoritative name server gets to hand out whatever answer it feels like. With it, tampering becomes detectable.
It becomes awkward when your registrar and your DNS host are not the same company. The registrar owns the relationship with the TLD. The DNS host owns the zone and the signing keys. DNSSEC only works when those two sides agree, and the only thing connecting them is a small record called a DS (Delegation Signer) that you copy by hand from one dashboard into another.
This post walks through the exact steps for a common split setup: the domain is registered at NameCheap, DNS is hosted at IONOS Cloud DNS (the one that comes with IONOS Data Center Designer, with name servers like ns-ic.ui-dns.com), and you want DNSSEC turned on. By the end, you will have:
- DNSSEC signing keys generated inside your IONOS zone
- A DS record published at the
.engineerTLD (or whichever TLD you use) via NameCheap - A validated chain of trust from the root zone all the way to your domain
Prerequisites:
- A domain at NameCheap with custom name servers pointing to IONOS
- An IONOS Cloud DNS zone already created and serving your records
- An IONOS API token — not a username/password, not a hosting-API key-pair; specifically a JWT-style Bearer token generated in Data Center Designer → Token Manager, or via
ionosctl token generate - A terminal with
curlandjqinstalled (brew install jqif you need it) - A rough understanding that you can break your domain’s resolution temporarily if you do this out of order — we will do it in the right order
Architecture: What Is Actually Happening
Before touching anything, it helps to know what the pieces are.
DNSSEC works by adding signatures to your DNS records. Those signatures are made with two keys:
- The Zone Signing Key (ZSK) signs your actual records (A, MX, TXT, and so on). Flag
256. - The Key Signing Key (KSK) signs the ZSK. Flag
257.
The KSK is the anchor. Its fingerprint is what you hand to the registrar, who hands it to the TLD, so that the parent zone can tell the world: “yes, this is the real KSK for this domain.” That fingerprint is the DS record. Everything else chains down from there.
This is why there are two sides:
- IONOS generates the keys and signs the zone. It does this internally once you tell it to — you never see or manage the ZSK directly.
- NameCheap publishes the DS record at the TLD. This is the handoff. The
.engineerregistry now knows your zone is signed and what key to trust.
If you publish a DS record that points at a key IONOS is not actually using, every validating resolver on the internet will treat your domain as broken. Google Public DNS, Cloudflare 1.1.1.1, Quad9 — they will all SERVFAIL. So the order is: keys at IONOS first, then DS at NameCheap. Not the other way around.
Step 1: Get an IONOS API Token
The IONOS Cloud DNS API lives at https://dns.de-fra.ionos.com and it takes a Bearer JWT. If you already have ionosctl installed, the fastest path is:
ionosctl token generateOtherwise, log into Data Center Designer, open the menu in the top-right, pick Token Manager, and generate a new token. Copy the whole value.
Export it into your shell so the rest of the commands stay readable:
export IONOS_TOKEN="paste-your-jwt-here"What this does: makes the token available as an environment variable so you do not have to paste it into every curl command. It lives for the life of the shell session and then disappears.
Sanity check that it works:
curl -sS -H "Authorization: Bearer $IONOS_TOKEN" \
"https://dns.de-fra.ionos.com/zones" \
| jq '.items[] | {id, name: .properties.zoneName}'You should see every zone you host at IONOS, one per JSON object. If you get a 401, the token is the wrong kind or has expired.
Step 2: Find Your Zone ID
Each IONOS zone is addressed by a UUID, not its domain name. Grab the ID for the zone you are working on:
export ZONE_ID=$(curl -sS -H "Authorization: Bearer $IONOS_TOKEN" \
"https://dns.de-fra.ionos.com/zones?filter.zoneName=example.engineer" \
| jq -r '.items[0].id')
echo "$ZONE_ID"Replace example.com with your domain. The echo is there so you can confirm you got a UUID back and not an empty string.
Step 3: Create the Signing Keys
This is the call that actually enables DNSSEC. It creates the KSK and ZSK, turns on signing, and publishes DNSKEY records inside your zone.
curl -sS -X POST \
-H "Authorization: Bearer $IONOS_TOKEN" \
-H "Content-Type: application/json" \
"https://dns.de-fra.ionos.com/zones/$ZONE_ID/keys" \
-d '{
"properties": {
"keyParameters": {
"algorithm": "RSASHA256",
"kskBits": 2048,
"zskBits": 1024
},
"nsecParameters": {
"nsecMode": "NSEC3",
"nsec3Iterations": 0,
"nsec3SaltBits": 64
},
"validity": 90
}
}' | jq .What this does — one field at a time:
algorithm: RSASHA256— DNSSEC algorithm 8. You might expect to use the more modernECDSAP256_SHA256(algorithm 13), and the IONOS API docs hint at it, but as of this writing IONOS Cloud DNS only acceptsRSASHA256. If you try ECDSA you will get a 422 telling you so. RSA is older and produces larger signatures, but it is universally supported and perfectly secure at 2048 bits.kskBits: 2048/zskBits: 1024— standard sizing for RSA DNSSEC keys. The KSK is larger because it is what the parent zone anchors to; the ZSK can be smaller because it rotates more frequently.nsecMode: NSEC3— NSEC3 resists zone walking, where an attacker can enumerate every record in your zone by asking for adjacent names. NSEC without the3makes that trivial. Always pick NSEC3 unless you have a specific reason not to.nsec3Iterations: 0— per RFC 9276, the recommended value is zero. Old guides will tell you to set it to 10 or 100; those guides are out of date and the modern position is that extra iterations mostly burn CPU for negligible benefit.validity: 90— how long each signature is valid for, in days. IONOS re-signs automatically before expiry. Ninety days is a fine default.
If the POST works, you get a JSON response echoing your parameters back. No error, no httpStatus. That means the keys exist.
Step 4: Retrieve the DS Record
Now ask for the keys back, which is where the DS information actually lives:
curl -sS -H "Authorization: Bearer $IONOS_TOKEN" \
"https://dns.de-fra.ionos.com/zones/$ZONE_ID/keys" | jq .You will get something like this (abridged):
{
"properties": {
"keyParameters": { "algorithm": "RSASHA256" },
"nsecParameters": { "nsecMode": "NSEC3" }
},
"metadata": {
"items": [
{
"composedKeyData": "257 3 8 AwEAAbTDvJmQkVcBk770vXhIdWZwloO...",
"digest": "D1F29E5C8AF05798E7E9889E245D87DC38A406FFCF6F352B5E85B379704EAFF4",
"digestAlgorithmMnemonic": "SHA-256",
"keyData": {
"flags": 257,
"pubKey": "AwEAAbTDvJmQkVcBk770vXhIdWZwloO..."
},
"keyTag": 9044
}
]
}
}Only one key comes back in the list and that is correct — IONOS only exposes the KSK, because the ZSK is never anything the outside world needs to see. You can confirm it is the KSK by the "flags": 257 value. A ZSK would be 256. The composedKeyData also starts with 257 3 8, which reads as: flags 257 (KSK), protocol 3, algorithm 8 (RSASHA256).
From that response you need exactly four values to give NameCheap:
| Field | Where to find it | Example value from above |
|---|---|---|
| Key Tag | keyTag | 9044 |
| Algorithm | derived from algorithm | 8 (RSA/SHA-256) |
| Digest Type | digestAlgorithmMnemonic | 2 (SHA-256) |
| Digest | digest | D1F29E5C8AF05798E7E9889E245D87DC38A406FFCF6F352B5E85B379704EAFF4 |
Algorithm numbers follow IANA’s DNSSEC registry: 8 is RSA/SHA-256, 13 is ECDSA P-256/SHA-256. Digest types are simpler: 1 is SHA-1 (avoid), 2 is SHA-256 (use this), 4 is SHA-384.
Step 5: Add the DS Record at NameCheap
This is the handoff. The four values above get pasted into NameCheap’s dashboard:
- Log into NameCheap, open Domain List, click Manage next to the domain.
- Go to the Advanced DNS tab.
- Scroll to the DNSSEC section. If there is a toggle, turn it on.
- Click Add DS Record and fill in the four fields. Some NameCheap UIs show Algorithm and Digest Type as dropdowns with names instead of numbers — pick RSA/SHA-256 for Algorithm and SHA-256 for Digest Type.
- Save.
Before you click save, check the digest string character by character. A single wrong hex character is the most common way to accidentally SERVFAIL your own domain. The mismatch will not surface as a gentle warning; validating resolvers will simply refuse to return any answer for your zone until the DS is fixed or the TTL on the bad record expires.
NameCheap says give it up to 60 minutes for propagation. For .engineer (and most newgTLDs), it usually lands in 10 to 20.
Step 6: Verify
You want to confirm three things: the DS exists at the TLD, the chain validates, and the ad (authenticated data) flag comes back on lookups.
# Is the DS published at the .engineer TLD?
dig +short DS example.engineer @a.gtld-servers.net
# Full validated lookup — you want "flags: qr rd ra ad" in the header
dig +dnssec +multi example.engineer SOA
# End-to-end trace, should complete without SERVFAIL
dig +trace +dnssec example.engineerIf you prefer a visual answer, two tools are worth bookmarking:
- DNSViz — graphs the chain from the root all the way to your zone, in color. Green is good.
- Verisign DNSSEC Analyzer — simpler pass/fail with plain-language explanations.
Both will also tell you if something is broken in a way that dig will not explain clearly.
Key Rollover: The Thing You Will Forget About
DNSSEC on this split setup has one ongoing cost: when you rotate the KSK, you have to update the DS record at NameCheap manually. IONOS will happily rotate ZSKs in the background forever, but the KSK is anchored to a DS record that only the registrar can change. If you ever delete and recreate keys at IONOS, the old DS at NameCheap becomes wrong and your domain goes dark.
Two practical implications:
- Do not casually delete and recreate the DNSSEC keys at IONOS. Treat that POST in Step 3 as a one-time action. If you need to rotate, add the new DS at NameCheap first, wait a TTL window, then remove the old one.
- Put a calendar reminder 60 to 80 days out to check that everything is still validating. If IONOS ever changes its signing setup or expires a key without rotating, you want to know before your users do.
Closing Thoughts
DNSSEC is, honestly, more bureaucratic than cryptographic once you have done it. The hard part is not the math — RSA signatures are well understood and the tooling has been stable for years. The hard part is that two separate companies have to agree on one string of hex, and nobody sends you a confirmation email when it is right.
The good news is that once the DS is published and the chain validates, there is not much to do. Your zone is signed, tampering is detectable, and every new record you add to the zone is signed automatically. It is one of the rare pieces of infrastructure where doing it once well replaces a recurring problem with a static one.
If you are getting into DNS infrastructure more broadly, you might also want to read blocky for the resolver-side view — the thing that actually consumes and validates the signatures you just set up.