DNS Cookies in BIND 9
  • 08 Nov 2023
  • 11 Minutes to read
  • Contributors
  • PDF

DNS Cookies in BIND 9

  • PDF

Article summary

DNS COOKIE is an Extended DNS (EDNS) option which, when both the client and server support it, allows the client to detect and ignore off-path spoofed responses, and the server to determine that a client's address is not spoofed.

BIND 9 supports DNS COOKIES in both the client/querying role (resolver querying an authoritative server) and the server/responding role (as an authoritative responding to a resolver or resolver responding to a stub client). The cookies are generated by both client and server, and exchanged between them. The server sends the client a cookie, which the client remembers (in BIND's case the client remembers for 1800 seconds) and includes in subsequent queries. The server only retains the client cookie for long enough to include it in the response to a query.

  • DNS COOKIES are enabled in all builds from BIND 9.11.0 forward. Note that the cookie policy was very lenient in the original implementation for a low-impact introduction, and is 'tightened' in BIND 9.11.26, 9.16.10, 9.17.8, and later versions, as described below.

The current version of the DNS Cookie standard implemented in BIND 9 is RFC 9018 "Interoperable Domain Name System (DNS) Cookies" that updates and clarifies RFC 7873 "Domain Name System (DNS) Cookies" in which the COOKIE option was originally defined.

Why would I want to use DNS Cookies?

Why would you not? Cookies are a low-cost, light-weight way to ensure that both parties in a DNS exchange know who they are talking to. DNS normally generates a high volume of UDP transactions, which are easily spoofed. Without cookies, both client and server must employ defensive actions to ensure they are not being misled or attacked by malicious parties spoofing the other end of the connection. Cookies are a well-known solution, deployed for decades in http connections, that provide some security benefits without the overhead of additional exchanges.

When implemented on the client, cookies can help reduce cache-poisoning type attacks. When implemented on the server, cookies identify legitimate repeat clients from a sea of spoofed-source queries, including DDOS attacks. The server can trust these 'known' clients with longer responses, and more responses, that might otherwise expose the authority to an amplification attack.

The benefits of DNS cookies will increase as deployment becomes more widespread. COOKIE, like all EDNS options, is deployable incrementally and independently, to facilitate gradual adoption.

How does BIND use DNS Cookies?

BIND as Server (Responder)

The default server behavior is to accept, but not require, cookies from clients sending queries. Some clients still do not support EDNS, and in some deployments EDNS packets are blocked by mis-configured firewalls. In normal operation, a BIND server will respond to a client whether or not a client cookie is presented with the query.

In BIND 9.11.0 and later versions, we use DNS Cookies to white-list known clients for Response Rate Limiting (RRL). Client queries associated with valid cookies will not be rate-limited. This benefits the client, and makes rate limiting more effective in mitigating abusive traffic, because rate limiting is able to focus on only those client queries not associated with cookies.

However, if BIND 9 receives a UDP request with a cookie that is invalid, it will return the rcode BADCOOKIE, including a correct server COOKIE. BIND can also be configured to require a server cookie if client cookie is present and will also return BADCOOKIE in this case.

BIND as Client (Requestor)

BIND as a client will send a client cookie in every query, and will also include a server cookie if it has one for that server.

In the initial and cautious implementation of cookies, BIND as client behaved very leniently towards servers that appeared to support DNS COOKIE but then responded with a missing or incorrect cookie:

  • If the cookie was included but incorrect, BIND would drop the response and wait for another response with a valid cookie.
  • If the cookie was missing, BIND accepted the response

In BIND 9.11.26, 9.16.10 and 9.17.8 and later versions, BIND implements stricter enforcement:
When a cookie is missing from a response from a server that previously offered a cookie, BIND will immediately fall back to TCP to attempt to positively identify the respondant. There is an exception: if the response is TSIG-signed, it is considered valid even without a cookie, and BIND will not fallback to TCP. (TSIG, even with relatively weak encryption such as HMAC-MD5, is considered a stronger proof of identity than a returned cookie).

There are various reasons why a cookie that is expected could be missing or incorrect. The cookie could be missing because the server has turned off DNS COOKIE support, or there is a misconfigured anycast server with partial DNS COOKIE support. It could be a sign of a spoofed response, which might indicate a cache poisoning attempt. Falling back to TCP is the correct behaviour in all 3 cases. This behavior change is not configurable.

If there are multiple BADCOOKIE responses received over UDP, BIND will switch to using TCP to make the request. This is intended to allow a client to still get answers from a misconfigured anycast server.

For DNS Cookies to be effective, both server and client need to support them
From BIND 9.11.0 DNS Cookie functionality is enabled by default and will be used by servers that deploy Response Rate Limiting. Administrators that upgrade their Authoritative servers to BIND 9.11.0 will have this feature automatically enabled and used with their RRL configuration. Administrators of Recursive servers that resolve queries on behalf of end user clients, when they upgrade to BIND 9.11.0, will be able to take advantage of DNS Cookies when communicating with Authoritative servers that also support their use.

What configuration options exist for DNS Cookies?

Please see the Administrator Reference Manuals (BIND 9.11.0 and newer) for more detail, but in summary:

  • send-cookie yes_or_no ;
    (Default yes). This is an option that is set globally or per-server and controls whether or not named will add a DNS COOKIE when sending queries to that server. It also controls the expectations of the behavior of a remote server that has responded previously with support for DNS Cookies. (In BIND 9.10 this was request-sit yes_or_no)
  • require-server-cookie yes_or_no ;
    (Default no). This controls how a server will respond to a COOKIE-aware client. When yes the server sends back BADCOOKIE if there isn't a server cookie included in the option and the client is expected to retry with the server cookie included.
  • nocookie-udp-size number ;
    Use this option if you need to change the default maximum UDP response size when responding to queries from clients that don't use DNS COOKIE (noting that max-udp-size may further limit the response size too)
  • cookie-secret secret-string ;
    If you're running an anycast cluster, you can use this option to pre-set the server cookie string (instead of having it automatically generated at start-up)
  • cookie-algorithm algorithm-id ;
    In the event that you want to change the way the default server COOKIE is generated at server start-up, this option changes the algorithm that is used. However, there's only a single algorithm siphash24 now, so there's no point in changing it.
  • answer-cookie yes_or_no ;
    Available in BIND 9.11.4, 9.12.2 and newer, this option allows you to disable server cookies. This would be exceptional and in most situations unnecessary, except where you are running your BIND servers as part of a heterogeneous anycast cluster in which there is no mechanism available to enable all the participating servers to share the same server cookie secret.

What if my server supports DNS Cookies but other servers don't?

DNS servers that are properly compliant with regards to EDNS options (RFC6891), even if they don't support DNS Cookies, should simply ignore it. The use of DNS Cookies is established by negotiation between the client and the server; if the negotiation does not take place then DNS Cookies will not be used and DNS queries and query responses will be sent and received as they would be before DNS Cookies were available.

If I want to enable DNS Cookies on my server, is there anything else I need to do in my network infrastructure?

If you are running servers that are using load-balancing, proxying, firewalling or other similar solutions between your clients and your servers, then you need to confirm that those other devices will handle properly the EDNS COOKIE option and subsequent Cookie negotiation. Use of Cookies is between two endpoints; this will influence the design of your DNS deployment if you wish to take advantage of DNS Cookie.

How do I manually generate a cookie-secret string (instead of having it automatically generated at start-up)?

The typical use-case for this would be for all the servers in an anycast set-up to share the same server cookie. If you want to specify cookie-secret yourself instead of allowing the system to generate a random cookie at start-up then you first need to know how many bits of secret that you need - and this is determined by the cookie-algorithm, either default or specified explicitly.

The allowed length of cookie secret for SipHash 2-4 cookie-algorithm is 128 bits (16 bytes).

Next, you need to generate a random secret.  One way to do this is to make use of the system's tools - typically openssl rand.

The following command (as an example) will generate 128 bits that can be used as a cookie-secret with AES:

$ openssl rand -hex 16
cd92d478f1700d634f024813c28189f4

This can then be used in named.conf like this:

cookie-secret "cd92d478f1700d634f024813c28189f4";

The advantage of generating cookie-secret locally is that you might be able to set the same secret for multiple DNS servers in the same cluster.

Another method for generating a secret string would be to use a publicly available source of randomness such as random.org:

https://www.random.org/cgi-bin/randbyte?nbytes=16&format=h

However, this method is not recommended as openssl command should be generally available on systems that are supported by BIND 9.

I don't want to enable DNS Cookies on my servers; do I need to do anything?

We strongly advise anyone running Authoritative DNS services to check that they are providing RFC-compliant services.

You can test whether your servers fully support EDNS via: https://ednscomp.isc.org/

Because EDNS Cookie is being deployed by many DNS server and client code providers, your servers will increasingly be encountering this EDNS option in received queries. You should ensure that your servers and any load-balancing, proxying, and firewalling devices that you operate are fully compliant with RFC6891.

Failure to support RFC6891 will cause DNS resolution failures and delays
This warning is primarily aimed at those running Authoritative DNS services. Failure to respond appropriately to queries that contain EDNS options, whether or not they are options that your servers support, may mean that your customers are unable to reach your servers as a result of DNS resolution failures and delays.

COOKIE, like all EDNS options, is theoretically incrementally and independently deployable. Servers that don't know about an EDNS option are supposed to ignore it (RFC6891). In practice, this is not always the case; about 10% of servers (as of June 2016) mishandle queries with unknown EDNS options in various ways. This is not normally fatal for DNS COOKIE; it just results in slightly slower lookups from these servers.

Nevertheless, mishandling of the COOKIE option has been known to cause errors that are fatal to name resolution when the resolver is validating responses coming from a signed zone, and the authoritative server returns either FORMERR or BADVERS, or fails to respond to the query. named treats these answers as if the server does not support EDNS (which it doesn't) so it stops sending any EDNS queries at all, which makes it impossible to get a DNSSEC response back. When testing against servers for the Alexa Top 1 Million names only a handful of servers behaved in this manner with signed zones, and the owners of these servers have been notified of the issue.

Mishandling of the COOKIE option can also trigger incorrect responses (such as NXDOMAIN or no NOERROR/NODATA, when there should have been a positive answer). This is usually caused by a misconfigured load-balancer.

I've enabled DNS Cookies on my Recursive Server and now I'm experiencing problems with some domains - what can I do?

Unfortunately, not all DNS server implementations are correct (this is not limited to support for EDNS - there are many circumstances in which Authoritative Servers respond improperly).

  • Upgrade your BIND 9 installation to the latest version. Since BIND 9.18.17, named will retry without DNS COOKIE on FORMERR if it appears that the FORMERR was due to the presence of a DNS COOKIE option. This should improve the compatibility with non-compliant remote DNS servers.

  • Use the send-cookie no; option inside the server clause in named.conf to disable sending the DNS COOKIE option to servers that fail completely.

How do I disable DNS Cookies on my server entirely?

We don't recommend doing this, except in extremis.  Most of the time, if you are running your servers correctly and professionally, the cause of your problems will lie elsewhere and should be addressed by other server administrators.  However, it is possible to disable the use of DNS COOKIE on your server entirely if you really need to (we hope that this is a temporary measure only):

You can globally disable sending the DNS COOKIE option by setting send-cookie no; within the options statement in named.conf

You can also globally disable responding to clients with a server DNS COOKIE in BIND 9.11.5 and BIND 9.11.2 and newer by using option "answer-cookie no;".

What tools are available for testing for and confirming DNS Cookies support?

You can test whether your servers fully support EDNS via: https://ednscomp.isc.org/.

By default, (new) dig will send requests with a DNS COOKIE option present. You can disable this with dig +nocookie.

On receiving a BADCOOKIE response, dig  will automatically retry with the correct cookie. You can disable this with dig +nobadcookie.

You can see the DNS COOKIE values being used by named to talk to servers in the named_dump.db file in the "Address database dump" sections.