-
Print
-
DarkLight
-
PDF
Two new configuration statements have been added to BIND for version 9.20.0. They are configurable options to allow operators of secondary servers and recursive resolvers to set an upper bound on the growth of data in their zones or caches.
Please note: these statements have also been added to the 9.18 major version in release 9.18.28 because they are required as the mitigation for CVE-2024-1737
The new statements are:
max-records-per-type
max-types-per-name
max-records-per-type
This statement can be used inside the options {
block, to set a global value for the server, inside a view {
block, if user-defined views are in use, or inside a zone <zone_name> {
block, to override both global and view settings, per zone.
From the CHANGES file:
Excessively large rdatasets can slow down database query processing, so a limit has been placed on the number of records that can be stored per rdataset, in a cache or zone database. This is configured with the new "max-records-per-type" option and defaults to 100.
For authoritative servers, what this means in practice is that (by default) BIND will now not load zones containing RRsets where a single owner name has greater than 100 records of the same type. For example:
name 300 IN A a.b.c.1
name 300 IN A a.b.c.2
...
name 300 IN A a.b.c.101
The graph below was derived during testing of the new option and shows the potential performance degradation as the value of this option is increased
The graph above has been produced from in-house testing, not field testing by customers. Therefore it should be taken only as an indication of the general shape of the potential performance hit and does not represent or guarantee values that might be achieved in real world installations.
max-types-per-name
This statement can also be used inside options {
, to set a global value for the server, or inside a view {
, if user-defined views are in use.
From the CHANGES file:
An excessively large number of rrtypes per owner can slow down database query processing, so a limit has been placed on the number of rrtypes that can be stored per owner (node) in a cache or zone database. This is configured with the new "max-types-per-name" option and defaults to 100. Default 100
For authoritative servers, what this means in practice is that (by default) BIND will now not load zones containing RRsets where a single name has greater than 100 records of different types. For example:
name 300 IN A a.b.c.1
name 300 IN AAAA aa:bb:cc::1
name 300 IN NS ns.mydomain.net.
...
The number of defined RRtypes is currently quite low, at around 50. However, the RRtype field has a length of 16 bits, allowing for 64k possible values. An attacker could fill a zone with many thousand RRs, all with the same name but of different (even though invalid) types, which would cause a server to slow down. Therefore this option limits that exposure by setting a ceiling on the number of different types permitted, per name.
Recursive servers
Recursive servers handle these new limits as follows.
If max-types-per-name
is set to a positive number, an attempt to add a new resource record set (from a received response) to a name in cache that already has the specified number of types will temporarily succeed, so that the query can be answered. However, once that operation has completed the newly added RRset will be purged immediately.
Certain high-priority RRtypes - including SOA, CNAME, DNSKEY, and their corresponding signatures - are always cached. If max-types-per-name
is set to a very low value then it may be ignored, to allow high-priority types to be cached.
If max-records-per-type
is set to a positive number, an attempt to add a new resource record set (from a received response) to a name in cache that already has the specified number of records will fail, the error will be logged and the client will be sent a SERVFAIL response.
Defaults and removal of the limits
The default value of 100 for both statements was chosen as a compromise, given the following operational considerations:
- A limit that (from experience of zone data) should be high enough for most use cases, including DNSSEC-signed data.
- A sufficiently low value that would cap performance degradation to no greater than about a third.
- A value that would be comfortably larger than know or planned RRtypes.
Both of these statements will accept a value of 0
, which removes the cap completely and causes BIND to behave as it did prior to 9.20 or 9.18.28.