diff options
author | Petr Spacek <pspacek@redhat.com> | 2016-05-04 10:30:18 +0200 |
---|---|---|
committer | Martin Basti <mbasti@redhat.com> | 2016-05-30 20:14:32 +0200 |
commit | da71e7e9de233bc0e40a90adb2db6d0944a1356a (patch) | |
tree | ca3a9d0f9b0d1d7c921275079c00ba0c9a27c796 | |
parent | 037eae26d0cd8467d3a559bb4cc585c61b626734 (diff) | |
download | freeipa-da71e7e9de233bc0e40a90adb2db6d0944a1356a.tar.gz freeipa-da71e7e9de233bc0e40a90adb2db6d0944a1356a.tar.xz freeipa-da71e7e9de233bc0e40a90adb2db6d0944a1356a.zip |
DNS: Warn if forwarding policy conflicts with automatic empty zones
Forwarding policy "first" or "none" may conflicts with some automatic empty
zones. Queries for zones specified by RFC 6303 will ignore
forwarding and recursion and always result in NXDOMAIN answers.
This is not detected and warned about. Global forwarding is equivalent
to forward zone ".".
Example:
Forward zone 1.10.in-addr.arpa with policy "first"
will not forward anything because BIND will automatically prefer
automatic empty zone "10.in-addr.arpa." which is authoritative.
https://fedorahosted.org/freeipa/ticket/5710
Reviewed-By: Martin Basti <mbasti@redhat.com>
-rw-r--r-- | ipalib/messages.py | 17 | ||||
-rw-r--r-- | ipalib/plugins/dns.py | 26 | ||||
-rw-r--r-- | ipatests/test_xmlrpc/test_dns_plugin.py | 14 |
3 files changed, 57 insertions, 0 deletions
diff --git a/ipalib/messages.py b/ipalib/messages.py index c760e9d37..e863bdd49 100644 --- a/ipalib/messages.py +++ b/ipalib/messages.py @@ -378,6 +378,23 @@ class FailedToRemoveHostDNSRecords(PublicMessage): "(%(reason)s)") +class DNSForwardPolicyConflictWithEmptyZone(PublicMessage): + """ + **13021** Forward zone 1.10.in-addr.arpa with policy "first" + will not forward anything because BIND automatically prefers + empty zone "10.in-addr.arpa.". + """ + + errno = 13021 + type = "warning" + format = _( + "Forwarding policy conflicts with some automatic empty zones. " + "Queries for zones specified by RFC 6303 will ignore " + "forwarding and recursion and always result in NXDOMAIN answers. " + "To override this behavior use forward policy 'only'." + ) + + def iter_messages(variables, base): """Return a tuple with all subclasses """ diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py index fdca0936f..51f5099b7 100644 --- a/ipalib/plugins/dns.py +++ b/ipalib/plugins/dns.py @@ -66,6 +66,7 @@ from ipalib.util import (normalize_zonemgr, from ipapython.dn import DN from ipapython.ipautil import CheckedIPAddress, check_zone_overlap from ipapython.dnsutil import DNSName +from ipapython.dnsutil import related_to_auto_empty_zone if six.PY3: unicode = str @@ -2079,6 +2080,20 @@ def _add_warning_fw_zone_is_not_effective(api, result, fwzone, version): ) +def _add_warning_fw_policy_conflict_aez(result, fwzone, **options): + """Warn if forwarding policy conflicts with an automatic empty zone.""" + fwd_policy = result['result'].get(u'idnsforwardpolicy', + dnsforwardzone.default_forward_policy) + if ( + fwd_policy != [u'only'] + and related_to_auto_empty_zone(DNSName(fwzone)) + ): + messages.add_message( + options['version'], result, + messages.DNSForwardPolicyConflictWithEmptyZone() + ) + + class DNSZoneBase(LDAPObject): """ Base class for DNS Zone @@ -4418,7 +4433,13 @@ class dnsconfig_mod(LDAPUpdate): result = super(dnsconfig_mod, self).execute(*keys, **options) self.obj.postprocess_result(result) + # this check makes sense only when resulting forwarders are non-empty + if result['result'].get('idnsforwarders'): + fwzone = DNSName('.') + _add_warning_fw_policy_conflict_aez(result, fwzone, **options) + if forwarders: + # forwarders were changed for forwarder in forwarders: try: validate_dnssec_global_forwarder(forwarder, log=self.log) @@ -4559,6 +4580,7 @@ class dnsforwardzone(DNSZoneBase): ) ) + @register() class dnsforwardzone_add(DNSZoneBase_add): __doc__ = _('Create new DNS forward zone.') @@ -4589,8 +4611,10 @@ class dnsforwardzone_add(DNSZoneBase_add): return dn def execute(self, *keys, **options): + fwzone = keys[-1] result = super(dnsforwardzone_add, self).execute(*keys, **options) self.obj._warning_fw_zone_is_not_effective(result, *keys, **options) + _add_warning_fw_policy_conflict_aez(result, fwzone, **options) if options.get('idnsforwarders'): self.obj._warning_if_forwarders_do_not_work( result, True, *keys, **options) @@ -4646,7 +4670,9 @@ class dnsforwardzone_mod(DNSZoneBase_mod): return dn def execute(self, *keys, **options): + fwzone = keys[-1] result = super(dnsforwardzone_mod, self).execute(*keys, **options) + _add_warning_fw_policy_conflict_aez(result, fwzone, **options) if options.get('idnsforwarders'): self.obj._warning_if_forwarders_do_not_work(result, False, *keys, **options) diff --git a/ipatests/test_xmlrpc/test_dns_plugin.py b/ipatests/test_xmlrpc/test_dns_plugin.py index 0953de8b5..7351d0b1d 100644 --- a/ipatests/test_xmlrpc/test_dns_plugin.py +++ b/ipatests/test_xmlrpc/test_dns_plugin.py @@ -1763,6 +1763,13 @@ class test_dns(Declarative): 'summary': None, u'messages': ( {u'message': lambda x: x.startswith( + u"Forwarding policy conflicts with some " + "automatic empty zones."), + u'code': 13021, + u'type': u'warning', + u'name': u'DNSForwardPolicyConflictWithEmptyZone', + u'data': {}}, + {u'message': lambda x: x.startswith( u"DNS server %s: query '. SOA':" % fwd_ip), u'code': 13006, u'type':u'warning', @@ -3438,6 +3445,13 @@ class test_forward_zones(Declarative): 'summary': None, u'messages': ( {u'message': lambda x: x.startswith( + u"Forwarding policy conflicts with some " + "automatic empty zones."), + u'code': 13021, + u'type': u'warning', + u'name': u'DNSForwardPolicyConflictWithEmptyZone', + u'data': {}}, + {u'message': lambda x: x.startswith( u"DNS server %s: query '%s SOA':" % (forwarder1, fwzone2)), u'code': 13006, |