diff --git a/data/templates/dns-forwarding/recursor.conf.tmpl b/data/templates/dns-forwarding/recursor.conf.tmpl index 8799718b..98560efa 100644 --- a/data/templates/dns-forwarding/recursor.conf.tmpl +++ b/data/templates/dns-forwarding/recursor.conf.tmpl @@ -29,5 +29,20 @@ local-address={{ listen_address | join(',') }} # dnssec dnssec={{ dnssec }} +# max-ttl +max-cache-ttl={{ advanced.max_ttl }} + +# pdns-option +{% for o in advanced.pdns_option %} +{{ o }} + +{% endfor %} + +# port +local-port={{ advanced.port }} + +# zones +auth-zones={% for z in 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.zone.conf.tmpl b/data/templates/dns-forwarding/recursor.zone.conf.tmpl new file mode 100644 index 00000000..c46787ed --- /dev/null +++ b/data/templates/dns-forwarding/recursor.zone.conf.tmpl @@ -0,0 +1,8 @@ +; +; Autogenerated by dns_forwarding.py +; + ; +{% for r in records %} +{{ r.name }} {{ r.type }} {{ r.preference }} {{ r.target }} +{% endfor %} + diff --git a/interface-definitions/dns-forwarding.xml.in b/interface-definitions/dns-forwarding.xml.in index 66b4db40..a4adbe98 100644 --- a/interface-definitions/dns-forwarding.xml.in +++ b/interface-definitions/dns-forwarding.xml.in @@ -182,6 +182,188 @@ 0.0.0.0 :: + + + Set advanced settings and DNS manipulations + + + + + Maximum amount of time requesting clients are allowed to cache replies + + u32:0-604800 + Seconds to cache records + + + + + + 86400 + + + + Specify pdns-recursor configuration command to be added directly to the config file + + text + setting command in pdns-recursor format + + + + + + + Set different listening port + + u32:1-65535 + Port to listen on + + + + + + 53 + + + + Set domain name to create/manipulate DNS zone for + + + + + Set A record name + + + + + Set IP address to be returned for specified domain + + ipv4 + Record IPv4 address + + + + + + + + #include + + + + + Set AAAA record name + + + + + Set IP address to be returned for specified domain + + ipv6 + Record IPv6 address + + + + + + + + #include + + + + + Set CNAME record name + + + #include + + + Set CNAME record target name + + text + Record target name + + + ^[-a-zA-Z0-9.]{0,63}$ + + + + + + + + Set MX record name + + + #include + + + Set MX destination hostname + + text + Record destination hostname + + + ^[-a-zA-Z0-9.]{0,63}$ + + + + + + Set preference for MX record + + 1-999 + Preference for MX record + + + + + + + + + + + Set PTR record name + + + #include + + + Set PTR record target + + text + Record target name + + + ^[-a-zA-Z0-9.]{0,63}$ + + + + + + + + Set TXT record name + + + #include + + + Set TXT record text content + + text + Record text content + + + + + + #include + + + + Use system name servers diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index c21a91a..355d063 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -81,6 +84,49 @@ def get_config(config=None): dns.update({'source_address_v4': source_address_v4}) dns.update({'source_address_v6': source_address_v6}) + advanced = dns.get('advanced', {}) + if 'pdns_option' not in advanced: + dns['advanced']['pdns_option'] = [] + dns['zones'] = [] + if 'zone' in advanced: + for node in advanced['zone']: + zonedata = advanced['zone'][node] + if 'disable' in zonedata: + continue + zone = { + 'name': node, + 'file': "{}/zone.{}.conf".format(pdns_rec_run_dir, node), + 'records': [], + } + for rtype in [ 'A', 'AAAA', 'CNAME', 'MX', 'PTR', 'TXT' ]: + if rtype not in zonedata: + continue + for subnode in zonedata[rtype]: + if 'disable' in zonedata[rtype][subnode]: + continue + preference = '10' + if 'preference' in zonedata[rtype][subnode]: + preference = zonedata[rtype][subnode]['preference'] + target = 'hostname' + if rtype in [ 'A', 'AAAA' ]: + target = 'address' + if rtype == 'TXT': + target = 'text' + if target not in zonedata[rtype][subnode]: + continue + targetdata = zonedata[rtype][subnode][target] if rtype in [ 'A', 'AAAA' ] else [ zonedata[rtype][subnode][target] ] + for item in targetdata: + if rtype == 'TXT': + item = "\"{}\"".format(item.replace("\"", "\\\"")) + record = { + 'name': subnode, + 'type': rtype, + 'preference': preference if rtype == 'MX' else '', + 'target': item, + } + zone['records'].append(record) + dns['zones'].append(zone) + return dns def verify(dns): @@ -119,6 +166,10 @@ 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 in dns['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'):