summaryrefslogtreecommitdiff
path: root/src/conf_mode/dns_forwarding.py
diff options
context:
space:
mode:
authorMarcus Hoff <marcus.hoff@ring2.dk>2020-09-26 13:19:37 +0200
committerMarcus Hoff <marcus.hoff@ring2.dk>2020-09-26 13:19:37 +0200
commit1141bee72677b25d18436975625d2d298be503ff (patch)
tree4b6dc8fe1a8ced931e1ba08c58a348abfcd85a6b /src/conf_mode/dns_forwarding.py
parent45b30adfaaec7065f768d04085138a75a76ed376 (diff)
parent374724be64728101c262fcac1579beece63ee651 (diff)
downloadvyos-1x-1141bee72677b25d18436975625d2d298be503ff.tar.gz
vyos-1x-1141bee72677b25d18436975625d2d298be503ff.zip
Merge remote-tracking branch 'upstream/current' into current
Diffstat (limited to 'src/conf_mode/dns_forwarding.py')
-rwxr-xr-xsrc/conf_mode/dns_forwarding.py176
1 files changed, 64 insertions, 112 deletions
diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py
index 53bc37882..5101c1e79 100755
--- a/src/conf_mode/dns_forwarding.py
+++ b/src/conf_mode/dns_forwarding.py
@@ -17,14 +17,17 @@
import os
from sys import exit
-from copy import deepcopy
from vyos.config import Config
+from vyos.configdict import dict_merge
from vyos.hostsd_client import Client as hostsd_client
-from vyos import ConfigError
-from vyos.util import call, chown
+from vyos.util import call
+from vyos.util import chown
+from vyos.util import vyos_dict_search
from vyos.template import render
+from vyos.xml import defaults
+from vyos import ConfigError
from vyos import airbag
airbag.enable()
@@ -35,136 +38,84 @@ pdns_rec_hostsd_lua_conf_file = f'{pdns_rec_run_dir}/recursor.vyos-hostsd.conf.l
pdns_rec_hostsd_zones_file = f'{pdns_rec_run_dir}/recursor.forward-zones.conf'
pdns_rec_config_file = f'{pdns_rec_run_dir}/recursor.conf'
-default_config_data = {
- 'allow_from': [],
- 'cache_size': 10000,
- 'export_hosts_file': 'yes',
- 'listen_address': [],
- 'name_servers': [],
- 'negative_ttl': 3600,
- 'system': False,
- 'domains': {},
- 'dnssec': 'process-no-validate',
- 'dhcp_interfaces': []
-}
-
hostsd_tag = 'static'
-def get_config(conf):
- dns = deepcopy(default_config_data)
+def get_config(config=None):
+ if config:
+ conf = config
+ else:
+ conf = Config()
base = ['service', 'dns', 'forwarding']
-
if not conf.exists(base):
return None
- conf.set_level(base)
-
- 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'])
- dns['cache_size'] = cache_size
-
- if conf.exists('negative-ttl'):
- negative_ttl = conf.return_value(['negative-ttl'])
- dns['negative_ttl'] = negative_ttl
-
- if conf.exists(['domain']):
- for domain in conf.list_nodes(['domain']):
- conf.set_level(base + ['domain', domain])
- entry = {
- 'nslist': bracketize_ipv6_addrs(conf.return_values(['server'])),
- 'addNTA': conf.exists(['addnta']),
- 'recursion-desired': conf.exists(['recursion-desired'])
- }
- dns['domains'][domain] = entry
-
- conf.set_level(base)
+ dns = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+ # We have gathered the dict representation of the CLI, but there are default
+ # options which we need to update into the dictionary retrived.
+ default_values = defaults(base)
+ dns = dict_merge(default_values, dns)
- if conf.exists(['ignore-hosts-file']):
- dns['export_hosts_file'] = "no"
+ # some additions to the default dictionary
+ if 'system' in dns:
+ base_nameservers = ['system', 'name-server']
+ if conf.exists(base_nameservers):
+ dns.update({'system_name_server': conf.return_values(base_nameservers)})
- if conf.exists(['name-server']):
- dns['name_servers'] = bracketize_ipv6_addrs(
- conf.return_values(['name-server']))
-
- if conf.exists(['system']):
- dns['system'] = True
-
- if conf.exists(['listen-address']):
- dns['listen_address'] = conf.return_values(['listen-address'])
-
- if conf.exists(['dnssec']):
- dns['dnssec'] = conf.return_value(['dnssec'])
-
- if conf.exists(['dhcp']):
- dns['dhcp_interfaces'] = conf.return_values(['dhcp'])
+ base_nameservers_dhcp = ['system', 'name-servers-dhcp']
+ if conf.exists(base_nameservers_dhcp):
+ dns.update({'system_name_server_dhcp': conf.return_values(base_nameservers_dhcp)})
return dns
-def bracketize_ipv6_addrs(addrs):
- """Wraps each IPv6 addr in addrs in [], leaving IPv4 addrs untouched."""
- return ['[{0}]'.format(a) if a.count(':') > 1 else a for a in addrs]
-
-def verify(conf, dns):
+def verify(dns):
# bail out early - looks like removal from running config
- if dns is None:
+ if not dns:
return None
- if not dns['listen_address']:
- raise ConfigError(
- "Error: DNS forwarding requires a listen-address")
-
- if not dns['allow_from']:
- raise ConfigError(
- "Error: DNS forwarding requires an allow-from network")
-
- if dns['domains']:
- for domain in dns['domains']:
- if not dns['domains'][domain]['nslist']:
- raise ConfigError((
- f'Error: No server configured for domain {domain}'))
-
- no_system_nameservers = False
- conf.set_level([])
- if dns['system'] and not (
- conf.exists(['system', 'name-server']) or
- conf.exists(['system', 'name-servers-dhcp']) ):
- no_system_nameservers = True
- print(("DNS forwarding warning: No 'system name-server' or "
- "'system name-servers-dhcp' set\n"))
-
- if (no_system_nameservers or not dns['system']) and not (
- dns['name_servers'] or dns['dhcp_interfaces']):
- print(("DNS forwarding warning: No 'dhcp', 'name-server' or 'system' "
- "nameservers set. Forwarding will operate as a recursor.\n"))
+ if 'listen_address' not in dns:
+ raise ConfigError('DNS forwarding requires a listen-address')
+
+ if 'allow_from' not in dns:
+ raise ConfigError('DNS forwarding requires an allow-from network')
+
+ # we can not use vyos_dict_search() when testing for domain servers
+ # as a domain will contains dot's which is out dictionary delimiter.
+ if 'domain' in dns:
+ for domain in dns['domain']:
+ if 'server' not in dns['domain'][domain]:
+ raise ConfigError(f'No server configured for domain {domain}!')
+
+ 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 " \
+ "name-servers-dhcp' configured")
return None
def generate(dns):
# bail out early - looks like removal from running config
- if dns is None:
+ if not dns:
return None
render(pdns_rec_config_file, 'dns-forwarding/recursor.conf.tmpl',
- dns, user=pdns_rec_user, group=pdns_rec_group)
+ dns, trim_blocks=True, user=pdns_rec_user, group=pdns_rec_group)
render(pdns_rec_lua_conf_file, 'dns-forwarding/recursor.conf.lua.tmpl',
- dns, user=pdns_rec_user, group=pdns_rec_group)
+ dns, trim_blocks=True, user=pdns_rec_user, group=pdns_rec_group)
# if vyos-hostsd didn't create its files yet, create them (empty)
- for f in [pdns_rec_hostsd_lua_conf_file, pdns_rec_hostsd_zones_file]:
- with open(f, 'a'):
+ for file in [pdns_rec_hostsd_lua_conf_file, pdns_rec_hostsd_zones_file]:
+ with open(file, 'a'):
pass
- chown(f, user=pdns_rec_user, group=pdns_rec_group)
+ chown(file, user=pdns_rec_user, group=pdns_rec_group)
return None
def apply(dns):
- if dns is None:
+ if not dns:
# DNS forwarding is removed in the commit
- call("systemctl stop pdns-recursor.service")
+ call('systemctl stop pdns-recursor.service')
+
if os.path.isfile(pdns_rec_config_file):
os.unlink(pdns_rec_config_file)
else:
@@ -174,8 +125,8 @@ def apply(dns):
# add static nameservers to hostsd so they can be joined with other
# sources
hc.delete_name_servers([hostsd_tag])
- if dns['name_servers']:
- hc.add_name_servers({hostsd_tag: dns['name_servers']})
+ if 'name_server' in dns:
+ hc.add_name_servers({hostsd_tag: dns['name_server']})
# delete all nameserver tags
hc.delete_name_server_tags_recursor(hc.get_name_server_tags_recursor())
@@ -184,32 +135,33 @@ def apply(dns):
# our own tag (static)
hc.add_name_server_tags_recursor([hostsd_tag])
- if dns['system']:
+ if 'system' in dns:
hc.add_name_server_tags_recursor(['system'])
else:
hc.delete_name_server_tags_recursor(['system'])
# add dhcp nameserver tags for configured interfaces
- for intf in dns['dhcp_interfaces']:
- hc.add_name_server_tags_recursor(['dhcp-' + intf, 'dhcpv6-' + intf ])
+ if 'system_name_server_dhcp' in dns:
+ for interface in dns['system_name_server_dhcp']:
+ hc.add_name_server_tags_recursor(['dhcp-' + interface,
+ 'dhcpv6-' + interface ])
# hostsd will generate the forward-zones file
# the list and keys() are required as get returns a dict, not list
hc.delete_forward_zones(list(hc.get_forward_zones().keys()))
- if dns['domains']:
- hc.add_forward_zones(dns['domains'])
+ if 'domain' in dns:
+ hc.add_forward_zones(dns['domain'])
# call hostsd to generate forward-zones and its lua-config-file
hc.apply()
### finally (re)start pdns-recursor
- call("systemctl restart pdns-recursor.service")
+ call('systemctl restart pdns-recursor.service')
if __name__ == '__main__':
try:
- conf = Config()
- c = get_config(conf)
- verify(conf, c)
+ c = get_config()
+ verify(c)
generate(c)
apply(c)
except ConfigError as e: