Why does bind allow TTL to be set record by records if different TTLs are not allowed within the same record set

Why does bind allow TTL to be set record by records if different TTLs are not allowed within the same record set?

If i set the zone ttl using:

$TTL 39600

And then set a record TTL using:

@        300     IN      A       1.1.1.1

I get the warning in my logs:

TTL set to prior TTL (300)

This is because I have "Different TTLs for records within the same record set, this is not allowed"

If this is not allowed, whats the point of being able to set TTL record by record?

Thanks


Solution 1:

The file format is specified in RFC1034 and parts of RFC1035. It is very old (1987), and not specifically defined for BIND or in light of current features. There is no great wisdom to be had here; it's like that by convention.

The format is also designed to be used for things like caches, I believe, though in practice this usage must be terribly rare. In a record cache, TTLs differ often and the cache contains records from many different domains.

Solution 2:

BIND allows you to set explicit TTLs for individual records that differ from the zone default TTL, but you cannot set different TTLs for records of the same type with the same name.

You can do this:

$TTL 39600
@        300     IN      A       192.0.2.100

You cannot do this:

$TTL 39600
@        300     IN      A       192.0.2.100
@                IN      A       192.0.2.101

Why? Because this would cause some records to time out from cache, leaving others behind, giving your users an incorrect answer to their DNS queries. For example, when you have two records of the same type with the same name, BIND will answer in a round-robin fashion, balancing the load between the two IP addresses. In the above example, 203.0.113.100 would time out after 5 minutes, leaving the other cached for 11 hours. The resolver would not re-query for the record with the shorter TTL because, as far as it knows, it has the answer for that A record query.

Here's a TXT record example:

$TTL 39600
@                IN      TXT     "My Google verification code"
@        300     IN      TXT     "My SPF record"
@        300     IN      TXT     "My DKIM record"
@        300     IN      TXT     "My DMARC record"

If the above example were allowed, a resolver would cache all 3 TXT records after a query, but my SPF, DKIM, and DMARC records would disappear after 5 minutes. Any mail server using this resolver would not be able to see these records and I would likely have problems with mail delivery.