summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/dns-forwarding/recursor.conf.tmpl44
-rwxr-xr-xsrc/conf_mode/dns_forwarding.py133
2 files changed, 88 insertions, 89 deletions
diff --git a/data/templates/dns-forwarding/recursor.conf.tmpl b/data/templates/dns-forwarding/recursor.conf.tmpl
new file mode 100644
index 000000000..9d1e019fa
--- /dev/null
+++ b/data/templates/dns-forwarding/recursor.conf.tmpl
@@ -0,0 +1,44 @@
+### Autogenerated by dns_forwarding.py ###
+
+# XXX: pdns recursor doesn't like whitespace near entry separators,
+# especially in the semicolon-separated lists of name servers.
+# Please be careful if you edit the template.
+
+# Non-configurable defaults
+daemon=yes
+threads=1
+allow-from={{ allow_from | join(',') }}
+log-common-errors=yes
+non-local-bind=yes
+query-local-address=0.0.0.0
+query-local-address6=::
+
+# cache-size
+max-cache-entries={{ cache_size }}
+
+# negative TTL for NXDOMAIN
+max-negative-ttl={{ negative_ttl }}
+
+# ignore-hosts-file
+export-etc-hosts={{ export_hosts_file }}
+
+# listen-on
+local-address={{ listen_on | join(',') }}
+
+# dnssec
+dnssec={{ dnssec }}
+
+# forward-zones / recursion
+#
+# statement is only inserted if either one forwarding domain or nameserver is configured
+# if nothing is given at all, powerdns will act as a real recursor and resolve all requests by its own
+#
+{% if name_servers or domains %}forward-zones-recurse=
+{%- for d in domains %}
+{{ d.name }}={{ d.servers | join(";") }}
+{{- ", " if not loop.last -}}
+{%- endfor -%}
+{%- if name_servers -%}
+{%- if domains -%}, {% endif -%}.={{ name_servers | join(';') }}
+{% endif %}
+{% endif %}
diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py
index 38f3cb4de..bbb69cdf7 100755
--- a/src/conf_mode/dns_forwarding.py
+++ b/src/conf_mode/dns_forwarding.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018 VyOS maintainers and contributors
+# Copyright (C) 2018-2020 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -13,76 +13,26 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-#
-import sys
import os
-
import argparse
-import jinja2
-import netifaces
-import vyos.util
-import vyos.hostsd_client
+from sys import exit
+from copy import deepcopy
+from jinja2 import FileSystemLoader, Environment
from vyos.config import Config
+from vyos.defaults import directories as vyos_data_dir
+from vyos.hostsd_client import Client as hostsd_client
+from vyos.util import wait_for_commit_lock
from vyos import ConfigError
-
parser = argparse.ArgumentParser()
parser.add_argument("--dhclient", action="store_true",
help="Started from dhclient-script")
config_file = r'/etc/powerdns/recursor.conf'
-# XXX: pdns recursor doesn't like whitespace near entry separators,
-# especially in the semicolon-separated lists of name servers.
-# Please be careful if you edit the template.
-config_tmpl = """
-### Autogenerated by dns_forwarding.py ###
-
-# Non-configurable defaults
-daemon=yes
-threads=1
-allow-from={{ allow_from | join(',') }}
-log-common-errors=yes
-non-local-bind=yes
-query-local-address=0.0.0.0
-query-local-address6=::
-
-# cache-size
-max-cache-entries={{ cache_size }}
-
-# negative TTL for NXDOMAIN
-max-negative-ttl={{ negative_ttl }}
-
-# ignore-hosts-file
-export-etc-hosts={{ export_hosts_file }}
-
-# listen-on
-local-address={{ listen_on | join(',') }}
-
-# dnssec
-dnssec={{ dnssec }}
-
-# forward-zones / recursion
-#
-# statement is only inserted if either one forwarding domain or nameserver is configured
-# if nothing is given at all, powerdns will act as a real recursor and resolve all requests by its own
-#
-{% if name_servers or domains %}forward-zones-recurse=
-{%- for d in domains %}
-{{ d.name }}={{ d.servers | join(";") }}
-{{- ", " if not loop.last -}}
-{%- endfor -%}
-{%- if name_servers -%}
-{%- if domains -%}, {% endif -%}.={{ name_servers | join(';') }}
-{% endif %}
-{% endif %}
-
-"""
-
default_config_data = {
'allow_from': [],
'cache_size': 10000,
@@ -96,74 +46,74 @@ default_config_data = {
def get_config(arguments):
- dns = default_config_data
+ dns = deepcopy(default_config_data)
conf = Config()
+ base = ['service', 'dns', 'forwarding']
if arguments.dhclient:
conf.exists = conf.exists_effective
conf.return_value = conf.return_effective_value
conf.return_values = conf.return_effective_values
- if not conf.exists('service dns forwarding'):
+ if not conf.exists(base):
return None
- conf.set_level('service dns forwarding')
+ conf.set_level(base)
- if conf.exists('allow-from'):
- dns['allow_from'] = conf.return_values('allow-from')
+ if conf.exists(['allow-from']):
+ dns['allow_from'] = conf.return_values(['allow-from'])
- if conf.exists('cache-size'):
- cache_size = conf.return_value('cache-size')
+ if conf.exists(['cache-size']):
+ cache_size = conf.return_value(['cache-size'])
dns['cache_size'] = cache_size
if conf.exists('negative-ttl'):
- negative_ttl = conf.return_value('negative-ttl')
+ negative_ttl = conf.return_value(['negative-ttl'])
dns['negative_ttl'] = negative_ttl
- if conf.exists('domain'):
- for node in conf.list_nodes('domain'):
- servers = conf.return_values("domain {0} server".format(node))
+ if conf.exists(['domain']):
+ for node in conf.list_nodes(['domain']):
+ servers = conf.return_values(['domain', node, 'server'])
domain = {
"name": node,
"servers": bracketize_ipv6_addrs(servers)
}
dns['domains'].append(domain)
- if conf.exists('ignore-hosts-file'):
+ if conf.exists(['ignore-hosts-file']):
dns['export_hosts_file'] = "no"
- if conf.exists('name-server'):
- name_servers = conf.return_values('name-server')
+ if conf.exists(['name-server']):
+ name_servers = conf.return_values(['name-server'])
dns['name_servers'] = dns['name_servers'] + name_servers
- if conf.exists('system'):
- conf.set_level('system')
+ if conf.exists(['system']):
+ conf.set_level(['system'])
system_name_servers = []
- system_name_servers = conf.return_values('name-server')
+ system_name_servers = conf.return_values(['name-server'])
if not system_name_servers:
- print(
- "DNS forwarding warning: No name-servers set under 'system name-server'\n")
+ print("DNS forwarding warning: No name-servers set under 'system name-server'\n")
else:
dns['name_servers'] = dns['name_servers'] + system_name_servers
- conf.set_level('service dns forwarding')
+ conf.set_level(base)
dns['name_servers'] = bracketize_ipv6_addrs(dns['name_servers'])
- if conf.exists('listen-address'):
- dns['listen_on'] = conf.return_values('listen-address')
+ if conf.exists(['listen-address']):
+ dns['listen_on'] = conf.return_values(['listen-address'])
- if conf.exists('dnssec'):
- dns['dnssec'] = conf.return_value('dnssec')
+ if conf.exists(['dnssec']):
+ dns['dnssec'] = conf.return_value(['dnssec'])
# Add name servers received from DHCP
- if conf.exists('dhcp'):
+ if conf.exists(['dhcp']):
interfaces = []
- interfaces = conf.return_values('dhcp')
- hc = vyos.hostsd_client.Client()
+ interfaces = conf.return_values(['dhcp'])
+ hc = hostsd_client()
for interface in interfaces:
- dhcp_resolvers = hc.get_name_servers("dhcp-{0}".format(interface))
- dhcpv6_resolvers = hc.get_name_servers("dhcpv6-{0}".format(interface))
+ dhcp_resolvers = hc.get_name_servers(f'dhcp-{interface}')
+ dhcpv6_resolvers = hc.get_name_servers(f'dhcpv6-{interface}')
if dhcp_resolvers:
dns['name_servers'] = dns['name_servers'] + dhcp_resolvers
@@ -202,7 +152,12 @@ def generate(dns):
if dns is None:
return None
- tmpl = jinja2.Template(config_tmpl, trim_blocks=True)
+ # Prepare Jinja2 template loader from files
+ tmpl_path = os.path.join(vyos_data_dir['data'], 'templates', 'dns-forwarding')
+ fs_loader = FileSystemLoader(tmpl_path)
+ env = Environment(loader=fs_loader, trim_blocks=True)
+
+ tmpl = env.get_template('recursor.conf.tmpl')
config_text = tmpl.render(dns)
with open(config_file, 'w') as f:
f.write(config_text)
@@ -223,7 +178,7 @@ if __name__ == '__main__':
if args.dhclient:
# There's a big chance it was triggered by a commit still in progress
# so we need to wait until the new values are in the running config
- vyos.util.wait_for_commit_lock()
+ wait_for_commit_lock()
try:
c = get_config(args)
@@ -232,4 +187,4 @@ if __name__ == '__main__':
apply(c)
except ConfigError as e:
print(e)
- sys.exit(1)
+ exit(1)