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.
- To use it in the BIND 9.10 branch, build BIND with "configure --enable-sit".
- It is enabled by default for Windows builds from BIND 9.10.3 and higher.
The COOKIE option is defined in [RFC7873]Cookie(https://www.ietf.org/rfc/rfc7873.txt),"Domain Name System (DNS) Cookies".
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-poisioning 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 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.
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:
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)
no). This controls how a server will respond to a COOKIE-aware client. When
yesthe 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.
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)
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)
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.
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?
How do I 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 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:
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.
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).
- Use the server clause in named.conf to disable sending the DNS COOKIE option to servers that fail completely
- In BIND 9.10.x the option to do this is "request-sit no; "
- From BIND 9.11.0 onwards, it is "send-cookie no; "
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 too (we hope that this is a temporary measure only):
You can globally disable sending the DNS COOKIE option within the Options statement in named.conf
- In BIND 9.10.x the option to do this is "request-sit no; "
- From BIND 9.11.0 onwards, it is "send-cookie no; "
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.