Sunday, July 10, 2022

How To Secure Your Domain Name With DNSSEC

The Domain Name System Security Extension (DNSSEC) is an extension that allows you to digitally sign DNS records for your domain name. This allows a DNS client that supports DNSSEC validation to authenticate all the DNS responses for your domain name. It is important to note that DNSSEC provides authentication but does not encrypt the data in transit. Thus it is possible for an attacker on the network to log the DNSSEC requests and responses, or block them all together.

This blog post is a continuation of the previous blog post that was about self hosting your own domain name. In this blog post we will take a look at how you can sign your self hosted domain name with DNSSEC. But first lets find out why you should sign your domain name and understand how DNSSEC validation works.

Technitium DNS Server Supports Both DNSSEC Signing And Validation

Why You Should Sign You Domain Name

This is a genuine question that comes up in everyone's mind considering that SSL/TLS certificates already protect your website from Man In The Middle (MiTM) attacks and also protect the data being transferred by encrypting it. 

Even then, there are many reasons to consider to sign your domain name, some of which are:

  • Most SSL/TLS certificates are issued based on domain name validation. This means an unsigned domain name that is vulnerable to spoofing, will allow an attacker to get a certificate issued for your domain name by spoofing responses to a Certificate Authority (CA) DNS requests during the certificate issue process. A signed domain name will prevent such attacks.
  • The CAA records that are used to indicate which CAs are authorized to issue a certificate for your domain name are secured when the domain name is signed. This prevents an attacker to get a certificate issued from unauthorized CAs by spoofing CAA responses.
  • Your HTTPS website is protected with SSL/TLS certificate since a user entering the domain name in the web browser that is matched with the certificate's subject. But your emails are not protected in that same manner. When an email is sent, the sender's mail server queries for MX records for your domain name to find out the mail servers that receive email for your domain name. If the domain name is unsigned, its possible to spoof the MX response to redirect your email to an attacker controlled mail server which then forwards the emails to your mail servers keeping a copy of all your emails.
  • Even when your domain name is signed, its possible for an attacker on the network path to downgrade a SMTP session such that STARTTLS fails causing your email to be transmitted in clear text. A signed domain name that has DANE configured for your mail servers will prevent such attacks.
  • DNS is also used to prove ownership of the domain name for many services that is usually done by publishing a TXT record with a given challenge string. An attacker can abuse such processes by spoofing TXT responses for unsigned domain name to prove ownership.
  • A signed domain name also protects itself from cache poisoning attacks on recursive resolvers that do DNSSEC validation. 

Signing your domain name thus protects your domain name as an owner from abuse or hijacks which otherwise are possible for an attacker with enough resources and motivation. Take a look at this video that explains how an attacker was able to performed an attack to hijack IMAP service that DNSSEC would have prevented.

How Does DNSSEC Validation Work?

DNSSEC uses public key cryptography to digitally sign the DNS records. The most commonly used algorithm is RSA but new algorithms like ECDSA, Ed25519, and Ed448 are also standardized.

The primary name server that hosts a DNSSEC signed zone has access to the secret private key being used to sign the zone while the corresponding public key is available as public DNSKEY record in the zone. Each record set in the zone, which is a group of records of same type, including the DNSKEY record set, is signed using the private key and the signature is stored as a RRSIG record. So, a DNS client can validate each record set by requesting for the DNSKEY records and use the public key from them to verify the signature in the RRSIG records in the DNS response.

To make sure that the DNSKEY records received by the DNS client itself are genuine, the DNS client has to fetch another set of DS (delegation signer) records from the parent zone. The DS record contains the hash of the DNSKEY record which the DNS client can use to validate the DNSKEY record that it has received. The DNSKEY which has a corresponding DS record published in the parent zone has a flag called Secure Entry Point (SEP) set to indicate that. The DS records from the parent zone itself are signed which the DNS client has to again validate against the DNSKEY records from the parent zone. The DNS client is configured with either DS records or DNSKEY records of the ROOT zone which acts as the trust anchor allowing the DNS client to validate a domain name and its parent zones up to the ROOT zone. This is called a chain of trust where having a trusted ROOT zone's DS records is sufficient for a DNS client to validate all domain names recursively.

The RRSIG records allow the DNS client to validate an existing record set but how does the signed zone prove that the requested type of record set or the sub domain name itself does not exists? This problem is solved using the NSEC (next secure) records which adds a level of complexity to DNSSEC. The signed zone has NSEC records for each sub domain names including the zone's apex and contains the domain name of the next NSEC record forming a kind of linked list that is sorted in an alphabetic order (canonical order). The last NSEC record contains the domain name of the first NSEC record. The NSEC records also lists the type of record sets that exist for that particular sub domain name. A DNS client using the NSEC records received for a request can validate if the requested domain does not exists (NXDOMAIN) or if there are no records for the requested type (NODATA).

The problem with the NSEC records, used to prove non-existence of domain name or a record type, is that the zone's entire structure gets published and thus anyone can use a technique called "zone walking" to list out all the sub domain names and all the record types for the zone. This is since NSEC records form a linked list and so the first NSEC record at the zone apex tells you the sub domain name of the next NSEC record which can be similarly followed to know all the sub domain names in that zone. This can be a problem if a zone contains private or internal records that must not be publicly disclosed. To fix this issue, another record type called NSEC3 (next secure 3) was introduced that uses hashing technique to mask the domain names that are visible in NSEC records. The NSEC3 record is also a kind of linked list similar to NSEC that can be used in similar way to prove non-existence of a domain or record set but the hashing of domain names in it adds another layer of complexity. The NSEC3 record makes it difficult for an attacker to perform "zone walking" but is not impossible for someone determined with resources to spare.

Configuration

The most common way to configure a signed zone is to have two sets of key pairs called Key Signing Key (KSK) and Zone Signing Key (ZSK). The KSK is the key pair for which a DS record is added in the parent zone and is used to sign only the DNSKEY records in the zone. While ZSK is the key pair that is used to sign all other types of records in the zone. This scheme of key management allows you to replace the ZSK (rollover the key) without the need to update any DS record at the parent zone making it possible to frequently change the ZSK. This also allows the private keys corresponding to KSK to be stored securely in a Hardware Security Module (HSM) which is only used when key rollover operation is required to be performed preventing KSK from being compromised. Technitium DNS Server implements KSK and ZSK keys to sign a zone but does not yet support HSM and thus all the private keys are stored in the zone file itself.

The most common reason for a signed domain name to fail validation and thus become inaccessible to users of validating DNS resolvers is misconfiguration caused during key rollover. The DNS records are highly cached at all levels. This means a record that has been deleted from the zone can still exists in caches of recursive resolvers, DNS proxies, OS, and even applications like web browsers. This makes it error prone to perform DNSSEC operations without help of proper tooling. The DNSSEC implementation done in Technitium DNS Server ensures that its easy and error free to configure and maintain a signed zone.

There are a few minimum requirements that you must check before proceeding to sign your zone:

  1. Check whether your Top Level Domain (TLD) is itself signed. You can only sign your zone if the parent zone too is signed. To check this, you can use the DNS Client tool to query for the TLD domain name with type set to DS. For example, if you domain is example.com, you should query for com as the domain name with type as DS. If you see one or more DS records in the answer section of the response then it means your TLD is signed and you can thus sign your zone.
  2. Make sure your zone does not use any proprietary ANAME or APP records. This is since those records generate a dynamic response which is not supported by the DNSSEC implementation. If you have any such records for a sub domain name then create another zone for the sub domain name for these type of records which will allow you to sign your main domain name independently. This ensures that your zone is signed except for those dynamic type of records in the sub domain zone.
  3. Check that all of your secondary name servers support DNSSEC. If you chose to use NSEC3 as the non-existence proof for your zone then make sure that NSEC3 too is supported by your secondary name servers.

Once you have confirmed all of the above requirements, you can proceed to sign your zone.

Signing Your Primary Zone

Proceed with the the steps below to sign your zone:

  1. Login to the DNS web console, go to the Zones section and click on the Edit button for your primary zone.
  2. In the zone view, click on the DNSSEC button at the top right corner to get a drop down menu. Click on the Sign Zone menu item to get the Sign Zone dialog box.

    The Primary Zone DNSSEC Drop Down Menu
  3. In the Sign Zone dialog box, select the recommended ECDSA algorithm as the DNSKEY algorithm and P256 as the ECDSA Curve.

    The Sign Zone Dialog Box
  4. Select the recommended NSEC as the Proof Of Non-Existence option. If your zone contains private/internal sub domain name records then you may use the NSEC3 option to hide them.
  5. Select a suitable DNSKEY TTL value which by default is set to 3600 sec (1 hour). A lower value allows quick addition or rollover of DNS keys but will cause frequent requests for the DNSKEY records.
  6. Select a suitable ZSK Automatic Rollover value which is the frequent at which the DNS server will rollover the ZSK to a new key automatically.
  7. After you have confirmed all the above values, click on the Sign Zone button to start the zone signing process.

When the zone signing process completes, you will see DNSSEC related records populated in the zone. Click on the DNSSEC button on the top right corner of the zone view and you will see a new drop down menu pop up. Click on the Properties menu item to see the DNSSEC Properties dialog box which shows you all the options that you entered while signing the zone to allow changing them later.

The DNSSEC Properties Dialog Box

Adding DS Record

Your zone is now signed but since you haven't added a DS record in the parent zone, the zone still cannot be validated by DNS clients and is still insecure. The next step is to add a DS record in the parent zone so that your zone can be validated and become secure. To do that, click on the DNSSEC button on the top right corner of the zone view and click on the View DS Info menu item to see the View DS Info dialog box. The View DS Info popup shows all the details required to add the DS record. But, before you add the DS record ensure that the Key State value shows Ready. If the DNSKEY was just published, you will see the Key State as Published with a "ready by" timestamp in brackets. The timestamp tells you when the Key State will switch from Published to Ready state. Once the Key State becomes Ready, you can proceed to add the DS record for your zone.

The Primary Zone View DS Info Dialog Box

WARNING! The most important thing to remember about signing the zone is that you MUST wait until the Key State of the DNSKEY with Secure Entry Point (SEP) flag becomes Ready before adding the DS record in the parent zone. If you do not wait, you risk your zone to fail validation for recursive resolvers that have old records still in their cache. The wait time to Ready state ensures that all the caches have expired.

Once the DNSKEY record's Key State becomes Ready, login to your domain registrar's web panel, find your domain name and click on the Manage option to view the domain details. Find the DNSSEC Management option in there which may be inside the Manage Nameservers option. Here you will find options to create DS records that will be automatically updated by your registrar into the parent zone.

The Create DS Record Form (For name.com Registrar)

The View DS Info popup displays all required values i.e. Key Tag, Algorithm, Digest Type, and Digests. For adding the DS record, use the provided Key Tag value, select the Algorithm number 13 i.e. ECDSAP256SHA256 that was used to sign your zone, the Digest Type as SHA-256, and Digest value provided against the digest type SHA256. Ensure that you have correctly entered all the values and proceed to create the DS record.

WARNING! If you make a mistake in adding the DS record then it will cause validation errors to resolve your domain name resulting in down time for your clients who use a DNS resolver with DNSSEC validation enabled. Thus its recommended that you cross check all the values a couple of times before proceeding to add the DS record.

NOTE! You need to add only one DS record per DNSKEY that has a Secure Entry Point (SEP) flag. You do not need to add DS record for each Digest Type hash values that you see in the zone for the DNSKEY record.

The DNS server keeps a watch on the DS record automatically every 15 minutes by querying the parent zone for it. Once it find the published DS record, the Key State of the DNSKEY will get changed from Ready to Active indicating that the zone can now be validated using the KSK DNSKEY record.

Testing Your Domain

You can now check for the DS record that was added using the DNS Client tool by querying for your domain name with type set to DS. For example, if your domain name is example.com use the same to query with the type as DS. If you get a response with DS record in the answer section then you can confirm once again the values it shows. Note that it may take a while for the DS record to be published by your Top Level Domain (TLD) so you should wait and try again after a while if you get an empty response for the DS query.

Once you see the DS record for your domain name in the DNS Client tool, you can proceed to test DNSSEC validation for your domain name. Check the Enable DNSSEC Validation option in the DNS Client tool, enter your domain name, select the record type as A, and click on the Resolve button. If everything is right then you will see response with answer section containing the A records with DnssecStatus property set to Secure.

Note! Do not use the DNS Client tab that is built into the DNS web console for the above test, instead use the DNS Client website to test since the built-in tool automatically trusts your local zones and thus will always validate the DNS records in the response as Secure hiding any issues that you may have with the DS record.

You can also try the DNSViz tool that will show you the signed zone's details visually as a diagram and will also show you any errors that you may have in your overall configuration.

Backup

Once you have your zone signed and tested it to be validating correctly, you MUST take a backup of your zone files since the private key that was used to sign your zone is stored in the zone file. In case your server hosting the zone crashes causing loss of data, you will face operational issues that can cause downtime for your domain name.

Take a backup using the Backup Settings option that you will find at the bottom right side in the Settings section of the DNS web console. You must select at least the DNS Zone Files check box to create the backup zip file that contains all of the zone files.

Since the private keys are stored in the zone files, the backup zip file must be stored securely to prevent the private keys from leaking to unauthorized people. The backup zip file will help you restore your zones in a cases of hardware failure.

It is recommended to take a periodic backup of your DNS server to make it easy to restore your server quickly in case of any failures.

Key Rollover

Similar to how SSL/TLS certificates have an expiry date upon which you need to renew them, you need to perform a key rollover operation for your KSK and ZSK in your signed zones too. You have to define a policy that tells the number of days to keep the keys and make an operating procedure to rollover the keys.

The key rollover operation generates a new key pair and retires the existing key pair. The process is automatic for ZSK as per the configuration you have in the DNSSEC properties for the zone. The number of days that you have set for rollover for the ZSK will be used by the DNS server to automatically trigger the rollover process. 

For KSK, you have to manually trigger the rollover since you have to manually add the DS records in the parent zone for the new DNSKEY record. It is recommended that you do the KSK rollover once every year as a policy.

For ZSK type keys, you can start the key rollover process manually too if you wish from the DNSSEC Properties dialog by clicking on the Rollover button for the key that you wish to rollover. Once you click the Rollover button, the DNS server will automatically generate and add a new key pair with Key State as Published. Once the new Key's State becomes Active, the old key will be retired and removed automatically. Since ZSK type keys have automatic rollover feature available, you would never require to manually trigger the rollover operation.

For KSK rollover, follow the steps given below:

  1. Open the DNSSEC Properties dialog and click on the Rollover button for the KSK key to start the process manually. This will cause the DNS server to generate and add a new key pair with Key State as Published.
  2. Note the Key Tag number for the new KSK and close the DNSSEC Properties dialog. Click on the refresh icon that you see next to your zone's name to refresh the displayed records. Find the new DNSKEY record corresponding to the new KSK using the noted Key Tag number displayed as Computed Key Tag for the DNSKEY record.
  3. Check the Key State for the DNSKEY record which will be Published with a "ready by" timestamp in the brackets, just like you had it when you first signed the zone. Similar to how you had to wait for the Key State to become Ready the first time, you have to wait again for the same. The timestamp will tell you when to come back to expect the Key State to become Ready.
  4. When the Key State for the DNSKEY record becomes Ready, you can login to your domain registrar's web panel and create a new DS record for the new DNSSEC record similar to how you added the first DS record.
  5. Once you have added the new DS record, find the old DS record and remove it. Make sure to confirm that you are removing the old DS record by matching its Key Tag value with the ones that you see in the zone's DNSSEC Properties dialog.

Once you have added the new DS record and removed the old DS record, the DNS server will automatically check for the updated DS record every 15 minutes by querying the parent zone. Once it finds the new DS record published, it will set the Key State for the new DNSKEY record from Ready to Active and the old DNSKEY record will be automatically retired and eventually removed.

You can again test once the new changes using DNS Client or DNSViz tools like you did earlier.

Conclusion

It is highly recommended for every domain owner to sign their domain names with DNSSEC to make them secure. Self hosting your domain name using Technitium DNS Server is easy and secure with DNSSEC. Technitium DNS Server's DNSSEC implementation makes it easy and error free to configure and manage your signed zones. With an easy to use key rollover process, there is no scope to have any misconfiguration issues that can cause downtime.

If you have any comments or queries, do let me know in the comments section below or send an email to support@technitium.com.

15 comments:

  1. Hi, Shreyas and thank you for you work.

    That about DNSSEC and DNS-server performance/resource usage?
    (i.e., how much does activating DNSSEC affect server performance and resource usage?)

    ReplyDelete
    Replies
    1. Thanks for asking. The overhead is not significant since the DNS server serves already signed records with their signatures. The signing happens only when you add/remove record and only for the affected records.

      The DNS server will serve RRSIG records in each response and has to also provide DNSKEY records for validation so average response size will increase slightly but wont be a noticeable issue.

      Delete
    2. Thank you, Shreyas, for your answer.

      Delete
  2. Does anyone know of registrars that allow updating the DS record via API? Google Domains doesn't have this capability.

    ReplyDelete
    Replies
    1. I don't know of any registrars that have API support to add DS records. But, since this is not a frequent operation, doing it once a year manually is still ok.

      Delete
    2. True, once a year is not bad, just need to make sure you don't forget about it. I just realized last week that a zone I use for testing had an expired DS record and that threw things off until I remembered. So I thought maybe some registrar had added an API that I could use from a triggered cron job, like with my LE certs.

      Delete
    3. DS records don't expire. Its a good policy to rollover keys just in case they may have been compromised similar to password changing policy. If you check the ROOT zone's current RSA 2048 KSK, it was generated in 2017.

      Delete
  3. I should have said the key in the DS record expired, not the actual DS record itself.

    ReplyDelete
    Replies
    1. Actually, nothing really expires in DNSSEC. The KSK/ZSK key pair can be used for as long as you wish. Its however recommended to rollover them at some suitable interval.

      The DS and DNSKEY records don't have any expiry. Only thing that expires are the RRSIG records which the DNS server automatically replaces before they expire.

      Delete
  4. I have a registry that is asking for the public key. How can I retrieve that? The registry has nowhere to input the computed digests or key tag.

    ReplyDelete
    Replies
    1. The public key is basically in the DNSKEY record with the SecureEntryPoint flag set that you see in the list of records. But having that public key is of no use since the parent zone has to add a DS record with the computed digest to secure the delegation from parent to child zone with DNSSEC.

      Which TLD registry are you using? Is the TLD zone DNSSEC signed?

      Delete
    2. Was trying with .nl and .nu both TLDs are signed as far as I can tell. I've also tried a couple different registries - both want the key, not just a DS record.

      Delete
    3. I've figured it out. Use dig to find the DNSKEY and insert that into your register if required. The key shown in shown in Technitium control panel doesn't seem to work.

      Delete
    4. Good to know that you get the DNSKEY from dig. You can get the same from the DNS Client tab on the DNS web console.

      Ya, the public key shown for the DNSKEY record in the web console is not in raw format but shows independent public key variables (x & y for ECDSA, and modulus and exponent for RSA). Will update the code to show the raw format instead in next release.

      Delete
  5. Is there any way to get the public key? My registry is requesting it and seems to be all they want. Nowhere to enter the computed digest or key tag.

    ReplyDelete