DNS cookies on servers in anycast clusters or behind load balancers
DNS Cookies - what are they?
In BIND 9.11 and newer, DNS Cookies are enabled automatically. This means that when queried by a client (which might itself be another DNS server, or just a resolver stub) that supports this option, BIND will respond with a server cookie. Similarly, when querying other servers, BIND as a resolver will offer a DNS cookie unless it has been configured not to do this (globally or per-server).
For more information about DNS Cookies, see https://kb.isc.org/docs/aa-01387 "DNS Cookies in BIND 9".
Potential Interoperability Problems
Most of the time, clients and servers that support DNS cookies will happily interoperate with clients and servers that do not and no special configuration options should be necessary. But there is one specific scenario where DNS server operators may need to pay attention and potentially make configuration changes.
This scenario is the anycast or load-balanced cluster - specifically one in which many servers are provisioned behind a single IP address, and where a client may be querying several different servers at different times, but presented to the client as a single server instance.
In that case, a client that supports DNS Cookies may find that the server cookie that it cached appears to change arbitrarily, or perhaps that sometimes the server supports DNS Cookies, and other times it does not.
Operating a Homogeneous Anycast or Load-balanced Cluster
If all of your DNS servers are running a version of BIND that supports DNS Cookies, then it is possible to generate your own cookie secret that they all share - this will ensure that they all respond identically.
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 default for cookie-algorithm is:
- AES (if your cryptographic library supports this) - cookie-secret 128 bits
- Otherwise SHA256 - cookie-secret 256 bits
If you explicitly set SHA1, then the cookie-secret would need 160 bits.
Next, you need to generate a random secret. One way to do this is to make use of the system's source of randomness - typically
/dev/random, but some operating environments might need instead
The following command (as an example) will generate 128 bits that can be used as a cookie-secret with AES:
$ dd if=/dev/random bs=16 count=1 | od -x 1+0 records in 1+0 records out 16 bytes transferred in 0.000029 secs (550073 bytes/sec) 0000000 8217 891b cbbc a1b7 9030 69d2 0d20 c4c2 0000020
This can then be used in named.conf like this:
The advantage of generating cookie-secret locally is that you might, for ease of system administration, want to script a process for updating it periodically.
Another method for generating a secret string would be to use a publicly available source of randomness such as random.org:
Operating a Heterogeneous Anycast or Load-balanced Cluster
If you are running a mixture of DNS servers - typically this is to introduce security by diversity by deploying DNS services from several different software providers - you may not be able to configure them to handle DNS cookies identically.
Unless it is causing actual operational problems, you should be able to just ignore the issue. Clients are supposed to handle multiple BADCOOKIE responses and switch over to TCP. (Both named and dig will do this).
RFC 7873 says:
If the extended RCODE in the reply is BADCOOKIE and the Client Cookie in the reply matches what was sent, it means that the server was unwilling to process the request because it did not have the correct Server Cookie in it. The client SHOULD retry the request using the new Server Cookie from the response. Repeated BADCOOKIE responses to requests that use the Server Cookie provided in the previous response may be an indication that either the shared secrets or the method for generating secrets in an anycast cluster of servers is inconsistent. If the reply to a retried request with a fresh Server Cookie is BADCOOKIE, the client SHOULD retry using TCP as the transport, since the server will likely process the request normally based on the security provided by TCP (see Section 5.2.3).
Nevertheless some operators may wish to disable DNS Cookies on their BIND servers.
In BIND 9.11.4, and BIND 9.12.2 and all newer versions of BIND, there is an option to disable server cookies:
answer-cookie no ;
How can I tell if I have a problem with DNS Cookies on my Anycast or Load-balanced Cluster servers?
As alluded to above, any problems encountered are likely to appear to be an intermittent issue responding to clients. What is happening is that clients that support DNS cookies have learned the server cookie of the first (or most recent) server in the cluster that they communicated with. They then send that cookie again to the server cluster, and this time a different server responds - with BADCOOKIE in the query response.
The servers may also 'fail' when the domain is tested at https://ednscomp.isc.org/ednscomp
YXRRSET. This is because this is the error code value when interpreting the bottom 4 bits of