From 36e5f07f8dda51cc5bb0a105077e751f1c851435 Mon Sep 17 00:00:00 2001 From: Lucas Christian Date: Thu, 7 Oct 2021 20:41:02 -0700 Subject: T562: Config syntax for defining DNS forward authoritative zones --- data/templates/dns-forwarding/recursor.conf.tmpl | 3 + .../recursor.vyos-hostsd.conf.lua.tmpl | 6 + .../dns-forwarding/recursor.zone.conf.tmpl | 7 + interface-definitions/dns-forwarding.xml.in | 452 ++++++++++++++++++++- .../include/dns/time-to-live.xml.i | 15 + python/vyos/hostsd_client.py | 12 + src/conf_mode/dns_forwarding.py | 206 +++++++++- src/services/vyos-hostsd | 36 +- 8 files changed, 730 insertions(+), 7 deletions(-) create mode 100644 data/templates/dns-forwarding/recursor.zone.conf.tmpl create mode 100644 interface-definitions/include/dns/time-to-live.xml.i diff --git a/data/templates/dns-forwarding/recursor.conf.tmpl b/data/templates/dns-forwarding/recursor.conf.tmpl index d44f756e8..02efe903b 100644 --- a/data/templates/dns-forwarding/recursor.conf.tmpl +++ b/data/templates/dns-forwarding/recursor.conf.tmpl @@ -31,5 +31,8 @@ dnssec={{ dnssec }} # serve rfc1918 records serve-rfc1918={{ 'no' if no_serve_rfc1918 is defined else 'yes' }} +# zones +auth-zones={% for z in authoritative_zones %}{{ z.name }}={{ z.file }}{{- "," if not loop.last -}}{% endfor %} + forward-zones-file=recursor.forward-zones.conf diff --git a/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.tmpl b/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.tmpl index 784d5c360..7f29c387e 100644 --- a/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.tmpl +++ b/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.tmpl @@ -22,3 +22,9 @@ addNTA("{{ zone }}", "static") {% endfor %} {% endif %} +{% if authoritative_zones is defined %} +-- from 'service dns forwarding authoritative-domain' +{% for zone in authoritative_zones %} +addNTA("{{ zone }}", "static") +{% endfor %} +{% endif %} diff --git a/data/templates/dns-forwarding/recursor.zone.conf.tmpl b/data/templates/dns-forwarding/recursor.zone.conf.tmpl new file mode 100644 index 000000000..758871bef --- /dev/null +++ b/data/templates/dns-forwarding/recursor.zone.conf.tmpl @@ -0,0 +1,7 @@ +; +; Autogenerated by dns_forwarding.py +; +; +{% for r in records %} +{{ r.name }} {{ r.ttl }} {{ r.type }} {{ r.value }} +{% endfor %} diff --git a/interface-definitions/dns-forwarding.xml.in b/interface-definitions/dns-forwarding.xml.in index 5b0c87597..ced138bff 100644 --- a/interface-definitions/dns-forwarding.xml.in +++ b/interface-definitions/dns-forwarding.xml.in @@ -105,6 +105,456 @@ + + + Domain to host authoritative records for + + text + An absolute DNS name + + + ^[-_a-zA-Z0-9.]{1,63}$ + + + + + + DNS zone records + + + + + "A" record + + text + A DNS name relative to the root record + + + @ + Root record + + + ^([-_a-zA-Z0-9.]{1,63}|@)(?<!\.)$ + + + + + + IPv4 address [REQUIRED] + + ipv4 + IPv4 address + + + + + + + + #include + #include + + + + + "AAAA" record + + text + A DNS name relative to the root record + + + @ + Root record + + + ^([-_a-zA-Z0-9.]{1,63}|@)(?<!\.)$ + + + + + + IPv6 address [REQUIRED] + + ipv6 + IPv6 address + + + + + + + + #include + #include + + + + + "CNAME" record + + text + A DNS name relative to the root record + + + @ + Root record + + + ^([-_a-zA-Z0-9.]{1,63}|@)(?<!\.)$ + + + + + + Target DNS name [REQUIRED] + + name.example.com + An absolute DNS name + + + ^[-_a-zA-Z0-9.]{1,63}(?<!\.)$ + + + + #include + #include + + + + + "MX" record + + text + A DNS name relative to the root record + + + @ + Root record + + + ^([-_a-zA-Z0-9.]{1,63}|@)(?<!\.)$ + + + + + + Mail server [REQUIRED] + + name.example.com + An absolute DNS name + + + ^[-_a-zA-Z0-9.]{1,63}(?<!\.)$ + + + + + + Server priority + + u32:1-999 + Server priority (lower numbers are higher priority) + + + + + + 10 + + + + #include + #include + + + + + "PTR" record + + text + A DNS name relative to the root record + + + @ + Root record + + + ^([-_a-zA-Z0-9.]{1,63}|@)(?<!\.)$ + + + + + + Target DNS name [REQUIRED] + + name.example.com + An absolute DNS name + + + ^[-_a-zA-Z0-9.]{1,63}(?<!\.)$ + + + + #include + #include + + + + + "TXT" record + + text + A DNS name relative to the root record + + + @ + Root record + + + ^([-_a-zA-Z0-9.]{1,63}|@)(?<!\.)$ + + + + + + Record contents [REQUIRED] + + text + Record contents + + + + + #include + #include + + + + + "SPF" record (type=SPF) + + text + A DNS name relative to the root record + + + @ + Root record + + + ^([-_a-zA-Z0-9.]{1,63}|@)(?<!\.)$ + + + + + + Record contents [REQUIRED] + + text + Record contents + + + + #include + #include + + + + + Host an DNS "SRV" record + + text + A DNS name relative to the root record + + + @ + Root record + + + ^([-_a-zA-Z0-9.]{1,63}|@)(?<!\.)$ + + + + + + Service entry [REQUIRED] + + u32:0-65535 + Entry number + + + + + + + + + Server hostname [REQUIRED] + + name.example.com + An absolute DNS name + + + ^[-_a-zA-Z0-9.]{1,63}(?<!\.)$ + + + + + + Port number [REQUIRED] + + u32:0-65535 + TCP/UDP port number + + + + + + + + + Entry priority + + u32:0-65535 + Entry priority (lower numbers are higher priority) + + + + + + 10 + + + + Entry weight + + u32:0-65535 + Entry weight + + + + + + 0 + + + + #include + #include + + + + + "NAPTR" record + + text + A DNS name relative to the root record + + + @ + Root record + + + ^([-_a-zA-Z0-9.]{1,63}|@)(?<!\.)$ + + + + + + NAPTR rule [REQUIRED] + + u32:0-65535 + Rule number + + + + + + + + + Rule order + + u32:0-65535 + Rule order (lower order is evaluated first) + + + + + + + + + Rule preference + + u32:0-65535 + Rule preference + + + + + + 0 + + + + "S" flag + + + + + + "A" flag + + + + + + "U" flag + + + + + + "P" flag + + + + + + Service type + + ^[a-zA-Z][a-zA-Z0-9]{0,31}(\+[a-zA-Z][a-zA-Z0-9]{0,31})?$ + + + + + + Regular expression + + + + + Replacement DNS name + + name.example.com + An absolute DNS name + + + ^[-_a-zA-Z0-9.]{1,63}(?<!\.)$ + + + + + + #include + #include + + + + + #include + + Do not use local /etc/hosts file in name resolution @@ -114,7 +564,7 @@ Makes the server authoritatively not aware of RFC1918 addresses - + diff --git a/interface-definitions/include/dns/time-to-live.xml.i b/interface-definitions/include/dns/time-to-live.xml.i new file mode 100644 index 000000000..5c1a1472d --- /dev/null +++ b/interface-definitions/include/dns/time-to-live.xml.i @@ -0,0 +1,15 @@ + + + + Time-to-live (TTL) + + u32:0-2147483647 + TTL in seconds + + + + + + 300 + + diff --git a/python/vyos/hostsd_client.py b/python/vyos/hostsd_client.py index 303b6ea47..f31ef51cf 100644 --- a/python/vyos/hostsd_client.py +++ b/python/vyos/hostsd_client.py @@ -79,6 +79,18 @@ class Client(object): msg = {'type': 'forward_zones', 'op': 'get'} return self._communicate(msg) + def add_authoritative_zones(self, data): + msg = {'type': 'authoritative_zones', 'op': 'add', 'data': data} + self._communicate(msg) + + def delete_authoritative_zones(self, data): + msg = {'type': 'authoritative_zones', 'op': 'delete', 'data': data} + self._communicate(msg) + + def get_authoritative_zones(self): + msg = {'type': 'authoritative_zones', 'op': 'get'} + return self._communicate(msg) + def add_search_domains(self, data): msg = {'type': 'search_domains', 'op': 'add', 'data': data} self._communicate(msg) diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index 06366362a..c2816589c 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -17,6 +17,7 @@ import os from sys import exit +from glob import glob from vyos.config import Config from vyos.configdict import dict_merge @@ -50,10 +51,12 @@ def get_config(config=None): if not conf.exists(base): return None - dns = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) + dns = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True, no_tag_node_value_mangle=True) # We have gathered the dict representation of the CLI, but there are default - # options which we need to update into the dictionary retrived. + # options which we need to update into the dictionary retrieved. default_values = defaults(base) + # T2665 due to how defaults under tag nodes work, we must clear these out before we merge + del default_values['authoritative_domain'] dns = dict_merge(default_values, dns) # some additions to the default dictionary @@ -66,6 +69,183 @@ def get_config(config=None): if conf.exists(base_nameservers_dhcp): dns.update({'system_name_server_dhcp': conf.return_values(base_nameservers_dhcp)}) + if 'authoritative_domain' in dns: + dns['authoritative_zones'] = [] + dns['authoritative_zone_errors'] = [] + for node in dns['authoritative_domain']: + zonedata = dns['authoritative_domain'][node] + if ('disable' in zonedata) || (not 'records' in zonedata): + continue + zone = { + 'name': node, + 'file': "{}/zone.{}.conf".format(pdns_rec_run_dir, node), + 'records': [], + } + + recorddata = zonedata['records'] + + for rtype in [ 'a', 'aaaa', 'cname', 'mx', 'ptr', 'txt', 'spf', 'srv', 'naptr' ]: + if rtype not in recorddata: + continue + for subnode in recorddata[rtype]: + if 'disable' in recorddata[rtype][subnode]: + continue + + rdata = recorddata[rtype][subnode] + + if rtype in [ 'a', 'aaaa' ]: + rdefaults = defaults(base + ['authoritative-domain', rtype]) # T2665 + rdata = dict_merge(rdefaults, rdata) + + if not 'address' in rdata: + dns['authoritative_zone_errors'].append('{}.{}: at least one address is required'.format(subnode, node)) + continue + + for address in rdata['address']: + zone['records'].append({ + 'name': subnode, + 'type': rtype.upper(), + 'ttl': rdata['ttl'], + 'value': address + }) + elif rtype in ['cname', 'ptr']: + rdefaults = defaults(base + ['authoritative-domain', rtype]) # T2665 + rdata = dict_merge(rdefaults, rdata) + + if not 'target' in rdata: + dns['authoritative_zone_errors'].append('{}.{}: target is required'.format(subnode, node)) + continue + + zone['records'].append({ + 'name': subnode, + 'type': rtype.upper(), + 'ttl': rdata['ttl'], + 'value': '{}.'.format(rdata['target']) + }) + elif rtype == 'mx': + rdefaults = defaults(base + ['authoritative-domain', rtype]) # T2665 + del rdefaults['server'] + rdata = dict_merge(rdefaults, rdata) + + if not 'server' in rdata: + dns['authoritative_zone_errors'].append('{}.{}: at least one server is required'.format(subnode, node)) + continue + + for servername in rdata['server']: + serverdata = rdata['server'][servername] + serverdefaults = defaults(base + ['authoritative-domain', rtype, 'server']) # T2665 + serverdata = dict_merge(serverdefaults, serverdata) + zone['records'].append({ + 'name': subnode, + 'type': rtype.upper(), + 'ttl': rdata['ttl'], + 'value': '{} {}.'.format(serverdata['priority'], servername) + }) + elif rtype == 'txt': + rdefaults = defaults(base + ['authoritative-domain', rtype]) # T2665 + rdata = dict_merge(rdefaults, rdata) + + if not 'value' in rdata: + dns['authoritative_zone_errors'].append('{}.{}: at least one value is required'.format(subnode, node)) + continue + + for value in rdata['value']: + zone['records'].append({ + 'name': subnode, + 'type': rtype.upper(), + 'ttl': rdata['ttl'], + 'value': "\"{}\"".format(value.replace("\"", "\\\"")) + }) + elif rtype == 'spf': + rdefaults = defaults(base + ['authoritative-domain', rtype]) # T2665 + rdata = dict_merge(rdefaults, rdata) + + if not 'value' in rdata: + dns['authoritative_zone_errors'].append('{}.{}: value is required'.format(subnode, node)) + continue + + zone['records'].append({ + 'name': subnode, + 'type': rtype.upper(), + 'ttl': rdata['ttl'], + 'value': '"{}"'.format(rdata['value'].replace("\"", "\\\"")) + }) + elif rtype == 'srv': + rdefaults = defaults(base + ['authoritative-domain', rtype]) # T2665 + del rdefaults['entry'] + rdata = dict_merge(rdefaults, rdata) + + if not 'entry' in rdata: + dns['authoritative_zone_errors'].append('{}.{}: at least one entry is required'.format(subnode, node)) + continue + + for entryno in rdata['entry']: + entrydata = rdata['entry'][entryno] + entrydefaults = defaults(base + ['authoritative-domain', rtype, 'entry']) # T2665 + entrydata = dict_merge(entrydefaults, entrydata) + + if not 'hostname' in entrydata: + dns['authoritative_zone_errors'].append('{}.{}: hostname is required for entry {}'.format(subnode, node, entryno)) + continue + + if not 'port' in entrydata: + dns['authoritative_zone_errors'].append('{}.{}: port is required for entry {}'.format(subnode, node, entryno)) + continue + + zone['records'].append({ + 'name': subnode, + 'type': rtype.upper(), + 'ttl': rdata['ttl'], + 'value': '{} {} {} {}.'.format(entrydata['priority'], entrydata['weight'], entrydata['port'], entrydata['hostname']) + }) + elif rtype == 'naptr': + rdefaults = defaults(base + ['authoritative-domain', rtype]) # T2665 + del rdefaults['rule'] + rdata = dict_merge(rdefaults, rdata) + + + if not 'rule' in rdata: + dns['authoritative_zone_errors'].append('{}.{}: at least one rule is required'.format(subnode, node)) + continue + + for ruleno in rdata['rule']: + ruledata = rdata['rule'][ruleno] + ruledefaults = defaults(base + ['authoritative-domain', rtype, 'rule']) # T2665 + ruledata = dict_merge(ruledefaults, ruledata) + flags = "" + if 'lookup-srv' in ruledata: + flags += "S" + if 'lookup-a' in ruledata: + flags += "A" + if 'resolve-uri' in ruledata: + flags += "U" + if 'protocol-specific' in ruledata: + flags += "P" + + if 'order' in ruledata: + order = ruledata['order'] + else: + order = ruleno + + if 'regexp' in ruledata: + regexp= ruledata['regexp'].replace("\"", "\\\"") + else: + regexp = '' + + if ruledata['replacement']: + replacement = '{}.'.format(ruledata['replacement']) + else: + replacement = '' + + zone['records'].append({ + 'name': subnode, + 'type': rtype.upper(), + 'ttl': rdata['ttl'], + 'value': '{} {} "{}" "{}" "{}" {}'.format(order, ruledata['preference'], flags, ruledata['service'], regexp, replacement) + }) + + dns['authoritative_zones'].append(zone) + return dns def verify(dns): @@ -86,6 +266,11 @@ def verify(dns): if 'server' not in dns['domain'][domain]: raise ConfigError(f'No server configured for domain {domain}!') + if dns['authoritative_zone_errors']: + for error in dns['authoritative_zone_errors']: + print(error) + raise ConfigError('Invalid authoritative records have been defined') + if 'system' in dns: if not ('system_name_server' in dns or 'system_name_server_dhcp' in dns): print("Warning: No 'system name-server' or 'system " \ @@ -104,6 +289,14 @@ def generate(dns): render(pdns_rec_lua_conf_file, 'dns-forwarding/recursor.conf.lua.tmpl', dns, user=pdns_rec_user, group=pdns_rec_group) + for zone_filename in glob(f'{pdns_rec_run_dir}/zone.*.conf'): + os.unlink(zone_filename) + + for zone in dns['authoritative_zones']: + render(zone['file'], 'dns-forwarding/recursor.zone.conf.tmpl', + zone, user=pdns_rec_user, group=pdns_rec_group) + + # if vyos-hostsd didn't create its files yet, create them (empty) for file in [pdns_rec_hostsd_lua_conf_file, pdns_rec_hostsd_zones_file]: with open(file, 'a'): @@ -119,6 +312,9 @@ def apply(dns): if os.path.isfile(pdns_rec_config_file): os.unlink(pdns_rec_config_file) + + for zone_filename in glob(f'{pdns_rec_run_dir}/zone.*.conf'): + os.unlink(zone_filename) else: ### first apply vyos-hostsd config hc = hostsd_client() @@ -153,6 +349,12 @@ def apply(dns): if 'domain' in dns: hc.add_forward_zones(dns['domain']) + # hostsd generates NTAs for the authoritative zones + # the list and keys() are required as get returns a dict, not list + hc.delete_authoritative_zones(list(hc.get_authoritative_zones())) + if 'authoritative_domain' in dns: + hc.add_authoritative_zones(list(dns['authoritative_domain'].keys())) + # call hostsd to generate forward-zones and its lua-config-file hc.apply() diff --git a/src/services/vyos-hostsd b/src/services/vyos-hostsd index 4c4bb036e..52753faa5 100755 --- a/src/services/vyos-hostsd +++ b/src/services/vyos-hostsd @@ -139,6 +139,27 @@ # } # # +### authoritative_zones +## Additional zones hosted authoritatively by pdns-recursor. +## We add NTAs for these zones but do not do much else here. +# +# { 'type': 'authoritative_zones', +# 'op': 'add', +# 'data': ['', ...] +# } +# +# { 'type': 'authoritative_zones', +# 'op': 'delete', +# 'data': ['', ...] +# } +# +# { 'type': 'authoritative_zones', +# 'op': 'get', +# } +# response: +# { 'data': ['', ...] } +# +# ### search_domains # # { 'type': 'search_domains', @@ -255,6 +276,7 @@ STATE = { "name_server_tags_recursor": [], "name_server_tags_system": [], "forward_zones": {}, + "authoritative_zones": [], "hosts": {}, "host_name": "vyos", "domain_name": "", @@ -267,7 +289,8 @@ base_schema = Schema({ Required('op'): Any('add', 'delete', 'set', 'get', 'apply'), 'type': Any('name_servers', 'name_server_tags_recursor', 'name_server_tags_system', - 'forward_zones', 'search_domains', 'hosts', 'host_name'), + 'forward_zones', 'authoritative_zones' 'search_domains', + 'hosts', 'host_name'), 'data': Any(list, dict), 'tag': str, 'tag_regex': str @@ -347,6 +370,11 @@ msg_schema_map = { 'delete': data_list_schema, 'get': op_type_schema }, + 'authoritative_zones': { + 'add': data_list_schema, + 'delete': data_list_schema, + 'get': op_type_schema + }, 'search_domains': { 'add': data_dict_list_schema, 'delete': data_list_schema, @@ -522,7 +550,7 @@ def handle_message(msg): data = get_option(msg, 'data') if _type in ['name_servers', 'forward_zones', 'search_domains', 'hosts']: delete_items_from_dict(STATE[_type], data) - elif _type in ['name_server_tags_recursor', 'name_server_tags_system']: + elif _type in ['name_server_tags_recursor', 'name_server_tags_system', 'authoritative_zones']: delete_items_from_list(STATE[_type], data) else: raise ValueError(f'Operation "{op}" unknown data type "{_type}"') @@ -534,7 +562,7 @@ def handle_message(msg): elif _type in ['forward_zones', 'hosts']: add_items_to_dict(STATE[_type], data) # maybe we need to rec_control clear-nta each domain that was removed here? - elif _type in ['name_server_tags_recursor', 'name_server_tags_system']: + elif _type in ['name_server_tags_recursor', 'name_server_tags_system', 'authoritative_zones']: add_items_to_list(STATE[_type], data) else: raise ValueError(f'Operation "{op}" unknown data type "{_type}"') @@ -550,7 +578,7 @@ def handle_message(msg): if _type in ['name_servers', 'search_domains', 'hosts']: tag_regex = get_option(msg, 'tag_regex') result = get_items_from_dict_regex(STATE[_type], tag_regex) - elif _type in ['name_server_tags_recursor', 'name_server_tags_system', 'forward_zones']: + elif _type in ['name_server_tags_recursor', 'name_server_tags_system', 'forward_zones', 'authoritative_zones']: result = STATE[_type] else: raise ValueError(f'Operation "{op}" unknown data type "{_type}"') -- cgit v1.2.3 From 9386ac0e3d7f3bd3b566fa67ad42e1be98057274 Mon Sep 17 00:00:00 2001 From: Lucas Christian Date: Tue, 12 Oct 2021 22:38:06 -0700 Subject: Fix error when no domains are defined --- src/conf_mode/dns_forwarding.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index c2816589c..278fa7226 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -74,7 +74,7 @@ def get_config(config=None): dns['authoritative_zone_errors'] = [] for node in dns['authoritative_domain']: zonedata = dns['authoritative_domain'][node] - if ('disable' in zonedata) || (not 'records' in zonedata): + if ('disable' in zonedata) or (not 'records' in zonedata): continue zone = { 'name': node, @@ -266,7 +266,7 @@ def verify(dns): if 'server' not in dns['domain'][domain]: raise ConfigError(f'No server configured for domain {domain}!') - if dns['authoritative_zone_errors']: + if ('authoritative_zone_errors' in dns) and dns['authoritative_zone_errors']: for error in dns['authoritative_zone_errors']: print(error) raise ConfigError('Invalid authoritative records have been defined') @@ -292,9 +292,10 @@ def generate(dns): for zone_filename in glob(f'{pdns_rec_run_dir}/zone.*.conf'): os.unlink(zone_filename) - for zone in dns['authoritative_zones']: - render(zone['file'], 'dns-forwarding/recursor.zone.conf.tmpl', - zone, user=pdns_rec_user, group=pdns_rec_group) + if 'authoritative_zones' in dns: + for zone in dns['authoritative_zones']: + render(zone['file'], 'dns-forwarding/recursor.zone.conf.tmpl', + zone, user=pdns_rec_user, group=pdns_rec_group) # if vyos-hostsd didn't create its files yet, create them (empty) -- cgit v1.2.3 From d6a79444ff131220529938b0ff849f43f3a9e1c0 Mon Sep 17 00:00:00 2001 From: Lucas Christian Date: Tue, 12 Oct 2021 22:51:29 -0700 Subject: Fix default values --- interface-definitions/dns-forwarding.xml.in | 2 +- src/conf_mode/dns_forwarding.py | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/interface-definitions/dns-forwarding.xml.in b/interface-definitions/dns-forwarding.xml.in index ced138bff..4faf604ad 100644 --- a/interface-definitions/dns-forwarding.xml.in +++ b/interface-definitions/dns-forwarding.xml.in @@ -360,7 +360,7 @@ - Host an DNS "SRV" record + "SRV" record text A DNS name relative to the root record diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index 278fa7226..5a5ae4d14 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -94,7 +94,7 @@ def get_config(config=None): rdata = recorddata[rtype][subnode] if rtype in [ 'a', 'aaaa' ]: - rdefaults = defaults(base + ['authoritative-domain', rtype]) # T2665 + rdefaults = defaults(base + ['authoritative-domain', 'records', rtype]) # T2665 rdata = dict_merge(rdefaults, rdata) if not 'address' in rdata: @@ -109,7 +109,7 @@ def get_config(config=None): 'value': address }) elif rtype in ['cname', 'ptr']: - rdefaults = defaults(base + ['authoritative-domain', rtype]) # T2665 + rdefaults = defaults(base + ['authoritative-domain', 'records', rtype]) # T2665 rdata = dict_merge(rdefaults, rdata) if not 'target' in rdata: @@ -123,7 +123,7 @@ def get_config(config=None): 'value': '{}.'.format(rdata['target']) }) elif rtype == 'mx': - rdefaults = defaults(base + ['authoritative-domain', rtype]) # T2665 + rdefaults = defaults(base + ['authoritative-domain', 'records', rtype]) # T2665 del rdefaults['server'] rdata = dict_merge(rdefaults, rdata) @@ -133,7 +133,7 @@ def get_config(config=None): for servername in rdata['server']: serverdata = rdata['server'][servername] - serverdefaults = defaults(base + ['authoritative-domain', rtype, 'server']) # T2665 + serverdefaults = defaults(base + ['authoritative-domain', 'records', rtype, 'server']) # T2665 serverdata = dict_merge(serverdefaults, serverdata) zone['records'].append({ 'name': subnode, @@ -142,7 +142,7 @@ def get_config(config=None): 'value': '{} {}.'.format(serverdata['priority'], servername) }) elif rtype == 'txt': - rdefaults = defaults(base + ['authoritative-domain', rtype]) # T2665 + rdefaults = defaults(base + ['authoritative-domain', 'records', rtype]) # T2665 rdata = dict_merge(rdefaults, rdata) if not 'value' in rdata: @@ -157,7 +157,7 @@ def get_config(config=None): 'value': "\"{}\"".format(value.replace("\"", "\\\"")) }) elif rtype == 'spf': - rdefaults = defaults(base + ['authoritative-domain', rtype]) # T2665 + rdefaults = defaults(base + ['authoritative-domain', 'records', rtype]) # T2665 rdata = dict_merge(rdefaults, rdata) if not 'value' in rdata: @@ -171,7 +171,7 @@ def get_config(config=None): 'value': '"{}"'.format(rdata['value'].replace("\"", "\\\"")) }) elif rtype == 'srv': - rdefaults = defaults(base + ['authoritative-domain', rtype]) # T2665 + rdefaults = defaults(base + ['authoritative-domain', 'records', rtype]) # T2665 del rdefaults['entry'] rdata = dict_merge(rdefaults, rdata) @@ -181,7 +181,7 @@ def get_config(config=None): for entryno in rdata['entry']: entrydata = rdata['entry'][entryno] - entrydefaults = defaults(base + ['authoritative-domain', rtype, 'entry']) # T2665 + entrydefaults = defaults(base + ['authoritative-domain', 'records', rtype, 'entry']) # T2665 entrydata = dict_merge(entrydefaults, entrydata) if not 'hostname' in entrydata: @@ -199,7 +199,7 @@ def get_config(config=None): 'value': '{} {} {} {}.'.format(entrydata['priority'], entrydata['weight'], entrydata['port'], entrydata['hostname']) }) elif rtype == 'naptr': - rdefaults = defaults(base + ['authoritative-domain', rtype]) # T2665 + rdefaults = defaults(base + ['authoritative-domain', 'records', rtype]) # T2665 del rdefaults['rule'] rdata = dict_merge(rdefaults, rdata) @@ -210,7 +210,7 @@ def get_config(config=None): for ruleno in rdata['rule']: ruledata = rdata['rule'][ruleno] - ruledefaults = defaults(base + ['authoritative-domain', rtype, 'rule']) # T2665 + ruledefaults = defaults(base + ['authoritative-domain', 'records', rtype, 'rule']) # T2665 ruledata = dict_merge(ruledefaults, ruledata) flags = "" if 'lookup-srv' in ruledata: -- cgit v1.2.3 From 98704f45a4d261ae472e9b299080a1f06275ae81 Mon Sep 17 00:00:00 2001 From: Lucas Christian Date: Tue, 12 Oct 2021 22:59:52 -0700 Subject: Don't generate NTA when zone is disabled --- src/conf_mode/dns_forwarding.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index 5a5ae4d14..23a16df63 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -353,8 +353,8 @@ def apply(dns): # hostsd generates NTAs for the authoritative zones # the list and keys() are required as get returns a dict, not list hc.delete_authoritative_zones(list(hc.get_authoritative_zones())) - if 'authoritative_domain' in dns: - hc.add_authoritative_zones(list(dns['authoritative_domain'].keys())) + if 'authoritative_zones' in dns: + hc.add_authoritative_zones(list(map(lambda zone: zone['name'], dns['authoritative_zones']))) # call hostsd to generate forward-zones and its lua-config-file hc.apply() -- cgit v1.2.3