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'):