Configuring DNSSEC signing and validation with Amazon Route 53
AWS now supports DNS Security Extensions (DNSSEC) signing on public zones for Amazon Route 53 and validation for Amazon Route 53 Resolver. DNSSEC is a specification that provides data integrity assurance for DNS and helps customers meet compliance mandates (for example, FedRAMP and security standards such as NIST). When you enable DNSSEC signing for a hosted zone, Route 53 adds cryptographic signatures to your DNS records. However, signing, by itself, is not sufficient to secure your zone. You also must establish a chain of trust to the zone. When you enable DNSSEC validation for your VPC in Route 53 Resolver, the resolver validates those signatures, confirming that no one tampered with the record. This helps protect you against DNS spoofing, cache poisoning, or other DNS-related man-in-the-middle attacks.
In this blog post, I’ll show you how to enable and disable DNSSEC signing for a hosted zone in Route 53, how to establish a chain of trust to the zone, how to rotate keys without downtime, and how to enable DNSSEC validation for a VPC.
Enabling hosted zone signing in Route 53
You can enable hosted zone signing using the AWS Management Console, CLI, or SDKs. In this post, I’ll show you how to do it by using the console.
- Sign in to the AWS Management Console.
- Navigate to your hosted zone in Route 53, and choose Enable DNSSEC signing.
- Next, you’ll have Route 53 create a key signing key (KSK). This is the key Route 53 uses to sign DNSKEY records, and is a critical piece of the DNSSEC validation process. Provide a name to identify the KSK, and then choose an existing customer managed key, or create a new one. If you decide to use an existing customer managed key, it must have specific characteristics, which are listed in the documentation here. For simplicity, I chose to create a new AWS KMS key. I gave it a name, and then chose Create KSK and enable signing.
- Finally, to help prevent a zone outage and avoid problems with your domain becoming unavailable, be aware that you must quickly address and resolve DNSSEC errors. I strongly recommend that you set up a CloudWatch alarm that alerts you whenever Route 53 returns a DNSSECInternalFailure or DNSSECKeySigningKeysNeedingAction error. For more information, see Monitoring hosted zones using Amazon CloudWatch.
Establishing a chain of trust
Next, you set up the chain of trust.
- On the DNSSEC signing tab for your hosted zone, choose View information to create DS record. This page contains information about how you can establish the chain of trust by updating your DNS to include a DS record that contains a hash of your KSK public key. Make this update at your domain registrar.
- If your domain is registered with Route 53, make the required updates for the chain of trust in the AWS Management Console. Navigate to Registered domains, select your domain name, and under DNSSEC status, choose Manage keys. Enter the information from the previous step on this page. If your domain is registered at another registrar, follow the instructions in the Another domain registrar section.
After your registrar adds the DS record for your domain name, you’re all set! Now clients querying your DNS records that use a DNSSEC-enabled resolver can confirm the authenticity of the information received.
If you prefer to use the CLI instead of the console to create a KSK and enable DNS signing for a hosted zone, do the following:
aws route53 create-key-signing-key --hosted-zone-id <hz-id> --key-management-service-arn <kms-key-arn> --name <ksk-name> --status ACTIVE --caller-reference <caller-reference> --region <region>
aws route53 enable-hosted-zone-dnssec --hosted-zone-id <hz-id> --region <region>
Note: After you run these commands to enable DNSSEC signing, you must follow the earlier steps to set up the chain of trust.
DNSSEC for child zones
To enable DNSSEC signing for a child zone, follow the same steps that you used for a registered domain name. Remember that to establish the chain of trust, you must add the DS record to the parent zone.
Note that for the chain of trust to work correctly, you must enable DNSSEC signing for the parent zone as well. For example, if I enable signing for subdomain1.example.aws, I add a DS record for subdomain1 to the zone example.aws. In addition, I must enable signing for example.aws for DNSSEC to work.
DNSSEC key rotation
Route 53 takes care of most DNSSEC complexities for you, including the handling and rotation of the zone signing key (ZSK). (I haven’t mentioned the ZSK before because Route 53 creates and manages the key for you.) However, you are responsible for rotating the KSK. You might have to perform this rotation every few months, depending on your security policy.
There are several ways to perform a successful KSK rotation. Here, I’ll show you how to rotate your KSKs using the double-RRset method. The basic steps for this method are to do the following:
- Add a new KSK and establish a chain of trust with it.
- Determine the time to live (TTL) values for the DNSKEY and DS records associated with the original KSK (the one you’re replacing).
- Remove the old DS record.
- Deactivate and delete the original KSK.
Incorrectly rotating your KSKs could break DNS resolution for the hosted zone so it’s important to follow the steps carefully.
To add a new KSK, do the following:
- Sign in to the AWS Management Console.
- Navigate to your hosted zone in Route 53, and then to the DNS signing section.
- In the Key signing keys (KSK) section, select Switch to advanced view, and then choose Add KSK.
- Provide a name for the new KSK, and then choose an existing customer managed key or create a new one. The customer managed key that you select must be different from the one that you used for the current KSK. Keep the KSK status as Active, and choose Add KSK.
- Select the KSK that you just created, and choose View details. Follow the instructions to add the new DS record at your registrar. Note that the method described here doesn’t replace the old DS record but instead adds a second DS record to the zone.
To determine the time to live (TTL) values, do the following:
- Determine the TTL of the DNSKEY record for the original KSK. To do this, determine the authoritative name server for the record, and then query the server directly. For example, you could run the following commands for the domain example.aws:
dig example.aws NS +short
dig example.aws DNSKEY @ns-452.awsdns-56.com
;; ANSWER SECTION:
example.aws. 3600 IN DNSKEY 256 3 13 LNKVN9x3UiSSSKglE2yh5Jcy2v0FKz0jWV1suB7WqME+xkYSubsG8blw GrWBdQ14TOonWpNBgtXhff7Lml02yA==
example.aws. 3600 IN DNSKEY 257 3 13 rCTT3fhLtCy0N1PK4NzdR071gAt2vFPRiGKJ/qOFakqpXBkMhSzD9HZXHPVnQr9fIM7WHvMtE96QAXmAdhggMQ==
The first query returns the nameservers for the example.aws domain’s records. I chose one of them (ns-452.awsdns-56.com), and specified it in the second query to return information about the DNSKEY record. In the results of the second query, I looked for the DNSKEY record that started with 257 and had the same public key as the old KSK. The second column shows the TTL (in seconds) of the record.
- Determine the TTL of the DS record. As with the DNSKEY record, first find the authoritative name server for the record, which is the nameserver of the parent domain. In my example, the parent domain is aws. Next, query the nameserver directly for information, which includes the TTL. For example, I ran the following commands for the domain example.aws:
dig aws NS +short
dig example.aws DS @dns1.nic.aws
;; ANSWER SECTION:
example.aws. 86400 IN DS 5037 13 2 84C6986D75148EEE3518455C41D7BF2CAB5AC5F9B4F6A69056D765FAF60153E4
The first query returns the nameservers for the aws domain’s records. I chose one of them (dns1.nic.aws), and specified it in the second query. The response to that query listed the TTL (in seconds) of the DS record, in the second column.
IMPORTANT: Wait an interval of at least the maximum of the TTL values returned by the queries (typically 2 days). The previous records are still cached until their TTLs expire, which means that some clients might still be using the old DS or DNSKEY records. If you complete the following step too soon, you could break the chain of trust, which might make your domain unavailable on the internet.
To remove the old DS record, do the following:
- If your domain is registered with Route 53, in the AWS Management Console, navigate to Registered domains, select your domain name, and under DNSSEC status, choose Manage keys. Delete the DNSSEC key corresponding to the old DS record.
- If your domain is registered at another registrar, follow the guidance at the registrar to remove the key.
To deactivate and delete the original KSK, do the following:
- On the DNSSEC signing tab of your hosted zone, select the radio button of the old KSK.
- Under Actions, choose Edit KSK.
- Choose Inactive, and then choose Save KSK.
- Select the radio button of the old KSK again, and then, under Actions, choose Delete KSK.
Disabling DNSSEC signing
To turn off DNSSEC for a hosted zone, you delete the DS record that you added when you enabled DNSSEC, and then confirm to Route 53 that you want to disable DNSSEC signing. After you delete the DS record, you must wait for the TTL of that record to expire (typically 2 days).
Important: If you don’t wait for the TTL of the DS record to expire before you continue, your domain could become unavailable on the internet.
After you delete the DS record and the TTL for the record expires, complete disabling DNSSEC signing by doing the following:
- In the AWS Management Console, go to the hosted zone for your domain.
- In the DNSSEC signing section, choose Disable DNSSEC signing.
- Affirm that you deleted the DS record, and confirm the change.
- Choose Disable.
The following screenshot shows the steps in the AWS Management Console. Important: If you disable DNSSEC signing before you turn off DNSSEC by deleting the DS record, your domain might become unavailable on the internet.
Enabling DNSSEC validation for a VPC
If you use Amazon Route 53 Resolver for VPCs, you can choose to enable DNSSEC validation on one or more of your VPCs. When you enable DNSSEC validation, when a domain is queried that has an invalid DNSSEC signature, it will resolve as SERVFAIL. Querying unsigned domains is not affected.
To enable DNSSEC validation, do the following:
- Sign in to the AWS Management Console, and on the Route 53 console, select VPCs.
- Select the VPC that you want to enable DNSSEC validation for.
- In the DNSSEC validation section, select Enable DNSSEC validation on this VPC. The Status changes to Enabling.
- Wait a few minutes for the status to change to Enabled.
Alternatively, you can use the AWS CLI to enable validation by doing the following:
aws route53resolver update-resolver-dnssec-config --resource-id <vpc-id> --validation ENABLE --region <region>
Testing DNSSEC validation
To test DNSSEC validation on your VPC, log in to an Amazon EC2 instance within the VPC, and then query a domain that is signed incorrectly. For example, you can query the domain dnssec-failed.org. If DNS validation is set up correctly for your VPC, you’ll see a SERVFAIL response, similar to the following:
Compatibility, cryptography, and risks
Finally, let’s look at some common questions around compatibility, encryption, and implementation risks with DNSSEC.
DNSSEC is backwards compatible with traditional DNS, which means that if you use a DNSSEC-enabled resolver, unsigned domains resolve just fine. If you use a DNS resolver that does not support DNSSEC, signed domains will resolve correctly too. However, no validation will be performed.
The following table illustrates the behavior for signed and unsigned domains, with and without DNSSEC validation enabled.
When I hear the word “cryptography,” I often associate it with encryption. However, although DNSSEC uses cryptographic keys, it does not encrypt DNS records. It uses the keys only for signing and validating signatures. In fact, DNSSEC does not modify your existing DNS records at all. It only adds special records that clients use to validate the authenticity of DNS responses.
There are some risks when you enable DNSSEC. The implementation is complex, it adds the task of maintaining and rotating keys, and if it’s set up incorrectly, DNSSEC might make your domain name unavailable on the internet. The good news is that Route 53 takes care of most of that complexity. When you follow the walkthroughs in this blog post, make sure that you follow the correct order of the steps, and pay attention to the minimum wait times (TTLs).
DNSSEC signing for Route 53 Public DNS and DNSSEC validation for Route 53 Resolver is available today. You can enable DNSSEC signing for all existing and new public hosted zones, and set up DNSSEC validation for your VPCs, by using the AWS Management Console, AWS Command Line Interface (CLI), or AWS SDKs. There is no extra charge to enable DNSSEC signing or validation, however, you do incur AWS KMS charges for the customer managed keys and signing requests. For more information, see the AWS KMS pricing page.
For more information on Route 53, visit the documentation here.