Source code for octodns.zone.ns

#
#
#

from .base import Zone
from .validator import ValidationReason, ZoneValidator


[docs] class GlueForInZoneNsZoneValidator(ZoneValidator): ''' Checks that NS records pointing to targets within the same zone have corresponding A or AAAA "glue" records. Without these address records, resolvers cannot follow the delegation because they would need to resolve the name server's address using the very name servers they are trying to locate. Example: - Zone ``example.com.`` has ``NS ns1.example.com.`` - This validator ensures an ``A`` or ``AAAA`` record exists for ``ns1.example.com.`` within the ``example.com.`` zone. Reference: https://datatracker.ietf.org/doc/html/rfc1033 (Operations) '''
[docs] def validate(self, zone): reasons = [] for record in zone.records: if record._type == 'NS': for target in record.values: # Is target in zone? if zone.owns('A', target): # Check if address records exist at this target hostname = zone.hostname_from_fqdn(target) # We need at least one A or AAAA addresses = zone.get(hostname, type='A') | zone.get( hostname, type='AAAA' ) if not addresses: reasons.append( ValidationReason( f'NS record "{record.fqdn}" points to in-zone target "{target}" without glue records (A/AAAA)', [record], ) ) return reasons
[docs] class NsTargetNotCnameZoneValidator(ZoneValidator): ''' Checks that NS records do not point to targets that are CNAMEs within the same zone. A CNAME target for NS is invalid because resolvers need the actual A/AAAA records to follow the delegation. '''
[docs] def validate(self, zone): reasons = [] for record in zone.records: if record._type == 'NS': for target in record.values: if zone.owns('CNAME', target): hostname = zone.hostname_from_fqdn(target) cnames = zone.get(hostname, type='CNAME') if cnames: reasons.append( ValidationReason( f'NS record "{record.fqdn}" points to target "{target}" which is a CNAME', [record], ) ) return reasons
[docs] class MultiValueNsZoneValidator(ZoneValidator): ''' Checks that all ``NS`` records have at least two values. Having multiple name servers is a fundamental best practice for DNS redundancy and availability, both at the apex and for sub-delegations. '''
[docs] def validate(self, zone): reasons = [] for record in zone.records: if record._type == 'NS': if len(record.values) < 2: reasons.append( ValidationReason( f'NS record "{record.fqdn}" has only {len(record.values)} value; at least 2 are recommended for redundancy', [record], ) ) return reasons
Zone.register_zone_validator( GlueForInZoneNsZoneValidator('glue-for-in-zone-ns', sets={'strict'}) ) Zone.register_zone_validator( MultiValueNsZoneValidator('multi-value-ns', sets={'best-practice'}) ) Zone.register_zone_validator( NsTargetNotCnameZoneValidator('ns-target-not-cname', sets={'strict'}) )