From 62461c73fd6e6616a48d6319d461d89239e4ee2f Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Wed, 10 Jun 2020 12:58:47 +0200 Subject: dns forwarding: T1595: remove references to old listen-on option As part of T1595 listen-on was removed and migrated to listen-address, but some references to it stayed in the variable names and validator error message. --- src/conf_mode/dns_forwarding.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index 692ac2456..efe169370 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -40,7 +40,7 @@ default_config_data = { 'allow_from': [], 'cache_size': 10000, 'export_hosts_file': 'yes', - 'listen_on': [], + 'listen_address': [], 'name_servers': [], 'negative_ttl': 3600, 'domains': [], @@ -103,7 +103,7 @@ def get_config(arguments): dns['name_servers'] = bracketize_ipv6_addrs(dns['name_servers']) if conf.exists(['listen-address']): - dns['listen_on'] = conf.return_values(['listen-address']) + dns['listen_address'] = conf.return_values(['listen-address']) if conf.exists(['dnssec']): dns['dnssec'] = conf.return_value(['dnssec']) @@ -134,9 +134,9 @@ def verify(dns): if dns is None: return None - if not dns['listen_on']: + if not dns['listen_address']: raise ConfigError( - "Error: DNS forwarding requires either a listen-address (preferred) or a listen-on option") + "Error: DNS forwarding requires a listen-address") if not dns['allow_from']: raise ConfigError( -- cgit v1.2.3 From 96595b42259e0e386e15f657857934fa20a55ca6 Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Thu, 11 Jun 2020 08:14:53 +0200 Subject: dns forwarding: T2486: add paths to files --- src/conf_mode/dns_forwarding.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index efe169370..26a651c3d 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -34,7 +34,11 @@ parser = argparse.ArgumentParser() parser.add_argument("--dhclient", action="store_true", help="Started from dhclient-script") -config_file = r'/run/powerdns/recursor.conf' +pdns_rec_run_dir = '/run/powerdns' +pdns_rec_lua_conf_file = f'{pdns_rec_run_dir}/recursor.conf.lua' +pdns_rec_hostsd_lua_conf_file = f'{pdns_rec_run_dir}/recursor.vyos-hostsd.conf.lua' +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': [], @@ -162,8 +166,8 @@ def apply(dns): if dns is None: # DNS forwarding is removed in the commit call("systemctl stop pdns-recursor.service") - if os.path.isfile(config_file): - os.unlink(config_file) + if os.path.isfile(pdns_rec_config_file): + os.unlink(pdns_rec_config_file) else: call("systemctl restart pdns-recursor.service") -- cgit v1.2.3 From 2b49fbf65aace72a9cd5629db48ae211e18a4e4a Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Thu, 11 Jun 2020 08:21:21 +0200 Subject: dns forwarding: T2486: remove unneeded --dhclient argument The functionality was moved to vyos-hostsd. --- src/conf_mode/dns_forwarding.py | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index 26a651c3d..188a39ef0 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -15,14 +15,12 @@ # along with this program. If not, see . import os -import argparse from sys import exit from copy import deepcopy from vyos.config import Config from vyos.hostsd_client import Client as hostsd_client -from vyos.util import wait_for_commit_lock from vyos import ConfigError from vyos.util import call from vyos.template import render @@ -30,10 +28,6 @@ from vyos.template import render from vyos import airbag airbag.enable() -parser = argparse.ArgumentParser() -parser.add_argument("--dhclient", action="store_true", - help="Started from dhclient-script") - pdns_rec_run_dir = '/run/powerdns' pdns_rec_lua_conf_file = f'{pdns_rec_run_dir}/recursor.conf.lua' pdns_rec_hostsd_lua_conf_file = f'{pdns_rec_run_dir}/recursor.vyos-hostsd.conf.lua' @@ -52,16 +46,11 @@ default_config_data = { } -def get_config(arguments): +def get_config(): 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(base): return None @@ -172,15 +161,10 @@ def apply(dns): call("systemctl restart pdns-recursor.service") if __name__ == '__main__': - args = parser.parse_args() - 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 - wait_for_commit_lock() try: - c = get_config(args) + c = get_config() verify(c) generate(c) apply(c) -- cgit v1.2.3 From 1eaf0077f2b42405d9bf8699dcf813c1b249d6fc Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Thu, 11 Jun 2020 08:24:06 +0200 Subject: dns forwarding: T2486: move Config() call into main As Config is required in both get_config and verify, init it once and pass it to both functions. --- src/conf_mode/dns_forwarding.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index 188a39ef0..aedfb2623 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -46,9 +46,8 @@ default_config_data = { } -def get_config(): +def get_config(conf): dns = deepcopy(default_config_data) - conf = Config() base = ['service', 'dns', 'forwarding'] if not conf.exists(base): @@ -122,7 +121,7 @@ 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(dns): +def verify(conf, dns): # bail out early - looks like removal from running config if dns is None: return None @@ -164,8 +163,9 @@ if __name__ == '__main__': try: - c = get_config() - verify(c) + conf = Config() + c = get_config(conf) + verify(conf, c) generate(c) apply(c) except ConfigError as e: -- cgit v1.2.3 From ba08187c069da93c943935ef60a78b506c035af0 Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Thu, 11 Jun 2020 08:32:33 +0200 Subject: dns forwarding: T2486: change internal representation of 'domain' config Change internal representation to the new one expected by vyos-hostsd. --- src/conf_mode/dns_forwarding.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index aedfb2623..36e2abb4a 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -41,7 +41,7 @@ default_config_data = { 'listen_address': [], 'name_servers': [], 'negative_ttl': 3600, - 'domains': [], + 'domains': {}, 'dnssec': 'process-no-validate' } @@ -67,13 +67,16 @@ def get_config(conf): dns['negative_ttl'] = negative_ttl 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) + 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'].append(domain) + dns['domains'][domain] = entry + + conf.set_level(base) if conf.exists(['ignore-hosts-file']): dns['export_hosts_file'] = "no" @@ -136,9 +139,9 @@ def verify(conf, dns): if dns['domains']: for domain in dns['domains']: - if not domain['servers']: - raise ConfigError( - 'Error: No server configured for domain {0}'.format(domain['name'])) + if not dns['domains'][domain]['nslist']: + raise ConfigError(( + f'Error: No server configured for domain {domain}')) return None -- cgit v1.2.3 From 7f2007964991b95166f4ab1255a57f4652c554ec Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Thu, 11 Jun 2020 08:33:46 +0200 Subject: dns forwarding: T2486: remove unnecessary intermediate name_servers variable --- src/conf_mode/dns_forwarding.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index 36e2abb4a..959c09bf8 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -82,8 +82,8 @@ def get_config(conf): dns['export_hosts_file'] = "no" if conf.exists(['name-server']): - name_servers = conf.return_values(['name-server']) - dns['name_servers'] = dns['name_servers'] + name_servers + dns['name_servers'] = bracketize_ipv6_addrs( + conf.return_values(['name-server'])) if conf.exists(['system']): conf.set_level(['system']) -- cgit v1.2.3 From e8da1c87f158898cdeb0ca3a16127701c7e8e28b Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Thu, 11 Jun 2020 08:34:39 +0200 Subject: dns forwarding: T2486: change internal handling of 'system' config node Remove manual retrieval of 'system name-server' from config and adding it to the name servers list, as this is now handled by simply adding a 'system' tag in vyos-hostsd. --- src/conf_mode/dns_forwarding.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index 959c09bf8..5ee8c53c2 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -41,6 +41,7 @@ default_config_data = { 'listen_address': [], 'name_servers': [], 'negative_ttl': 3600, + 'system': False, 'domains': {}, 'dnssec': 'process-no-validate' } @@ -86,16 +87,7 @@ def get_config(conf): conf.return_values(['name-server'])) if conf.exists(['system']): - conf.set_level(['system']) - system_name_servers = [] - 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") - else: - dns['name_servers'] = dns['name_servers'] + system_name_servers - conf.set_level(base) - - dns['name_servers'] = bracketize_ipv6_addrs(dns['name_servers']) + dns['system'] = True if conf.exists(['listen-address']): dns['listen_address'] = conf.return_values(['listen-address']) -- cgit v1.2.3 From f02f9622307687282aeca2600953cf6394f09485 Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Thu, 11 Jun 2020 08:36:08 +0200 Subject: dns forwarding: T2486: change internal handling of 'dhcp' nameservers Remove the old solution that retrieved dhcp tagged nameservers from hostsd and added it to nameservers, as it didn't work anyway (only once during configuration but it didn't update them later). This is now handled by vyos-hostsd, just retrieve the configured interfaces and send it the list of tags to use. --- src/conf_mode/dns_forwarding.py | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index 5ee8c53c2..556947733 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -43,7 +43,8 @@ default_config_data = { 'negative_ttl': 3600, 'system': False, 'domains': {}, - 'dnssec': 'process-no-validate' + 'dnssec': 'process-no-validate', + 'dhcp_interfaces': [] } @@ -95,20 +96,8 @@ def get_config(conf): if conf.exists(['dnssec']): dns['dnssec'] = conf.return_value(['dnssec']) - # Add name servers received from DHCP if conf.exists(['dhcp']): - interfaces = [] - interfaces = conf.return_values(['dhcp']) - hc = hostsd_client() - - for interface in interfaces: - 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 - if dhcpv6_resolvers: - dns['name_servers'] = dns['name_servers'] + dhcpv6_resolvers + dns['dhcp_interfaces'] = conf.return_values(['dhcp']) return dns -- cgit v1.2.3 From d6d72d37606849607979d410db75d1803f18f159 Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Thu, 11 Jun 2020 08:37:15 +0200 Subject: dns forwarding: T2486: add warning for no dhcp, system or static nameservers Add warning that forwarding will operate as a recursor in case there are no nameservers configured. --- src/conf_mode/dns_forwarding.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/conf_mode') diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index 556947733..06bdab12b 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -124,6 +124,19 @@ def verify(conf, dns): raise ConfigError(( f'Error: No server configured for domain {domain}')) + no_system_nameservers = False + 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")) + return None def generate(dns): -- cgit v1.2.3 From 8b3f96e58b865bcaf31d7eca80c7e2edaf9482f2 Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Thu, 11 Jun 2020 08:39:15 +0200 Subject: dns forwarding: T2486: generate recursor conf files - generate recursor.conf, recursor.conf.lua - if recursor.vyos-hostsd.conf.lua and recursor.forward-zones.conf don't exist, create empty ones (they are/will be generated by vyos-hostsd) --- src/conf_mode/dns_forwarding.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index 06bdab12b..1d5ee84a4 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -22,12 +22,13 @@ from copy import deepcopy from vyos.config import Config from vyos.hostsd_client import Client as hostsd_client from vyos import ConfigError -from vyos.util import call +from vyos.util import call, chown from vyos.template import render from vyos import airbag airbag.enable() +pdns_rec_user = pdns_rec_group = 'pdns' pdns_rec_run_dir = '/run/powerdns' pdns_rec_lua_conf_file = f'{pdns_rec_run_dir}/recursor.conf.lua' pdns_rec_hostsd_lua_conf_file = f'{pdns_rec_run_dir}/recursor.vyos-hostsd.conf.lua' @@ -144,7 +145,18 @@ def generate(dns): if dns is None: return None - render(config_file, 'dns-forwarding/recursor.conf.tmpl', dns, trim_blocks=True, user='pdns', group='pdns') + render(pdns_rec_config_file, 'dns-forwarding/recursor.conf.tmpl', + dns, 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) + + # 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'): + pass + chown(f, user=pdns_rec_user, group=pdns_rec_group) + return None def apply(dns): -- cgit v1.2.3 From 66165fa536eb75c046c2dc3f1efcf1f85b2b68ae Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Thu, 11 Jun 2020 08:50:48 +0200 Subject: dns forwarding: T2486: configure vyos-hostsd Removes and adds all required settings. --- src/conf_mode/dns_forwarding.py | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index 1d5ee84a4..51631dc16 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -48,6 +48,7 @@ default_config_data = { 'dhcp_interfaces': [] } +hostsd_tag = 'static' def get_config(conf): dns = deepcopy(default_config_data) @@ -166,11 +167,44 @@ def apply(dns): if os.path.isfile(pdns_rec_config_file): os.unlink(pdns_rec_config_file) else: - call("systemctl restart pdns-recursor.service") + ### first apply vyos-hostsd config + hc = hostsd_client() -if __name__ == '__main__': + # 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']}) + + # delete all nameserver tags + hc.delete_name_server_tags_recursor(hc.get_name_server_tags_recursor()) + + ## add nameserver tags - the order determines the nameserver order! + # our own tag (static) + hc.add_name_server_tags_recursor([hostsd_tag]) + + if dns['system']: + 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 ]) + # 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']) + + # call hostsd to generate forward-zones and its lua-config-file + hc.apply() + + ### finally (re)start pdns-recursor + call("systemctl restart pdns-recursor.service") + +if __name__ == '__main__': try: conf = Config() c = get_config(conf) -- cgit v1.2.3 From b3af8156e774198b5ca14bb6b21084a95ef1a256 Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Thu, 11 Jun 2020 08:53:57 +0200 Subject: host_name: T2486: change internal 'static-host-mapping' representation Change internal representation to the one required by vyos-hostsd. --- src/conf_mode/host_name.py | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py index dbc587d7d..a4794f041 100755 --- a/src/conf_mode/host_name.py +++ b/src/conf_mode/host_name.py @@ -42,6 +42,7 @@ default_config_data = { 'domain_search': [], 'nameserver': [], 'no_dhcp_ns': False + 'static_host_mapping': {} } def get_config(): @@ -69,15 +70,10 @@ def get_config(): hosts['no_dhcp_ns'] = True # system static-host-mapping - hosts['static_host_mapping'] = [] - - if conf.exists('system static-host-mapping host-name'): - for hn in conf.list_nodes('system static-host-mapping host-name'): - mapping = {} - mapping['host'] = hn - mapping['address'] = conf.return_value('system static-host-mapping host-name {0} inet'.format(hn)) - mapping['aliases'] = conf.return_values('system static-host-mapping host-name {0} alias'.format(hn)) - hosts['static_host_mapping'].append(mapping) + for hn in conf.list_nodes('system static-host-mapping host-name'): + hosts['static_host_mapping'][hn] = {} + hosts['static_host_mapping'][hn]['address'] = conf.return_value(f'system static-host-mapping host-name {hn} inet') + hosts['static_host_mapping'][hn]['aliases'] = conf.return_values(f'system static-host-mapping host-name {hn} alias') return hosts @@ -108,14 +104,22 @@ def verify(config): raise ConfigError( 'The search list is currently limited to 256 characters') + all_static_host_mapping_addresses = [] # static mappings alias hostname - if config['static_host_mapping']: - for m in config['static_host_mapping']: - if not m['address']: - raise ConfigError('IP address required for ' + m['host']) - for a in m['aliases']: - if not hostname_regex.match(a) and len(a) != 0: - raise ConfigError('Invalid alias \'{0}\' in mapping {1}'.format(a, m['host'])) + for host, hostprops in hosts['static_host_mapping'].items(): + if not hostprops['address']: + raise ConfigError(f'IP address required for static-host-mapping "{host}"') + if hostprops['address'] in all_static_host_mapping_addresses: + raise ConfigError(( + f'static-host-mapping "{host}" address "{hostprops["address"]}"' + f'already used in another static-host-mapping')) + all_static_host_mapping_addresses.append(hostprops['address']) + for a in hostprops['aliases']: + if not hostname_regex.match(a) and len(a) != 0: + raise ConfigError(f'Invalid alias "{a}" in static-host-mapping "{host}"') + + # TODO: add warnings for nameservers_dhcp_interfaces if interface doesn't + # exist or doesn't have address dhcp(v6) return None -- cgit v1.2.3 From 7343e0e184a15eb56dc0ae1ee9bbc8ef60871704 Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Thu, 11 Jun 2020 08:54:42 +0200 Subject: host_name: T2486: remove domain-search length limitations Debian Buster doesn't have the length and character limitations of /etc/resolv.conf 'search' any more, it is unlimited. https://sourceware.org/bugzilla/show_bug.cgi?id=19569 (glibc >2.26) --- src/conf_mode/host_name.py | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py index a4794f041..4fe7b4cbd 100755 --- a/src/conf_mode/host_name.py +++ b/src/conf_mode/host_name.py @@ -78,32 +78,21 @@ def get_config(): return hosts -def verify(config): - if config is None: +def verify(conf, hosts): + if hosts is None: return None # pattern $VAR(@) "^[[:alnum:]][-.[:alnum:]]*[[:alnum:]]$" ; "invalid host name $VAR(@)" hostname_regex = re.compile("^[A-Za-z0-9][-.A-Za-z0-9]*[A-Za-z0-9]$") - if not hostname_regex.match(config['hostname']): - raise ConfigError('Invalid host name ' + config["hostname"]) + if not hostname_regex.match(hosts['hostname']): + raise ConfigError('Invalid host name ' + hosts["hostname"]) # pattern $VAR(@) "^.{1,63}$" ; "invalid host-name length" - length = len(config['hostname']) + length = len(hosts['hostname']) if length < 1 or length > 63: raise ConfigError( 'Invalid host-name length, must be less than 63 characters') - # The search list is currently limited to six domains with a total of 256 characters. - # https://linux.die.net/man/5/resolv.conf - if len(config['domain_search']) > 6: - raise ConfigError( - 'The search list is currently limited to six domains') - - tmp = ' '.join(config['domain_search']) - if len(tmp) > 256: - raise ConfigError( - 'The search list is currently limited to 256 characters') - all_static_host_mapping_addresses = [] # static mappings alias hostname for host, hostprops in hosts['static_host_mapping'].items(): -- cgit v1.2.3 From 77081a6585fb64c1dba32c97eaaa54cf6a8741d9 Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Thu, 11 Jun 2020 08:59:04 +0200 Subject: host_name: T2486: replace disable-dhcp-nameservers with name-servers-dhcp The previous implementation only supported disabling DHCP nameservers for all interfaces, and was implemented improperly so it didn't work anyway. It's safe to remove it completely. This adds support for a new config node name-servers-dhcp , which allows us to enable just the interfaces we want to use for system DNS, identical in syntax to 'service dns forwarding dhcp '. The new option works by adding tags to vyos-hostsd that we want to use to add nameservers to resolv.conf, same as adding tags for dns forwarding but for a different destination file. A config migrator will be added in a separate commit. --- src/conf_mode/host_name.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py index 4fe7b4cbd..a71f9f88f 100755 --- a/src/conf_mode/host_name.py +++ b/src/conf_mode/host_name.py @@ -41,7 +41,7 @@ default_config_data = { 'domain_name': '', 'domain_search': [], 'nameserver': [], - 'no_dhcp_ns': False + 'nameservers_dhcp_interfaces': [], 'static_host_mapping': {} } @@ -66,8 +66,7 @@ def get_config(): if conf.exists("system name-server"): hosts['nameserver'] = conf.return_values("system name-server") - if conf.exists("system disable-dhcp-nameservers"): - hosts['no_dhcp_ns'] = True + hosts['nameservers_dhcp_interfaces'] = conf.return_values("system name-servers-dhcp") # system static-host-mapping for hn in conf.list_nodes('system static-host-mapping host-name'): -- cgit v1.2.3 From 71e088fbb42dbbb899dfe73989c306609a9b1135 Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Thu, 11 Jun 2020 09:02:35 +0200 Subject: host_name: T2486: move Config() call into main Init Config once in main() and pass it to both get_config() and verify(). --- src/conf_mode/host_name.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py index a71f9f88f..4652050ab 100755 --- a/src/conf_mode/host_name.py +++ b/src/conf_mode/host_name.py @@ -45,8 +45,7 @@ default_config_data = { 'static_host_mapping': {} } -def get_config(): - conf = Config() +def get_config(conf): hosts = copy.deepcopy(default_config_data) if conf.exists("system host-name"): @@ -176,8 +175,9 @@ def apply(config): if __name__ == '__main__': try: - c = get_config() - verify(c) + conf = Config() + c = get_config(conf) + verify(conf, c) generate(c) apply(c) except ConfigError as e: -- cgit v1.2.3 From 49eab6aaf392d631e041a99239407f953c2d5e64 Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Thu, 11 Jun 2020 09:04:24 +0200 Subject: host_name: T2486: remove conf.exists calls The getter methods will return empty values if config nodes don't exist, so there's no point in checking if they exist before. --- src/conf_mode/host_name.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py index 4652050ab..6cefab2fd 100755 --- a/src/conf_mode/host_name.py +++ b/src/conf_mode/host_name.py @@ -48,12 +48,12 @@ default_config_data = { def get_config(conf): hosts = copy.deepcopy(default_config_data) - if conf.exists("system host-name"): - hosts['hostname'] = conf.return_value("system host-name") - # This may happen if the config is not loaded yet, - # e.g. if run by cloud-init - if not hosts['hostname']: - hosts['hostname'] = default_config_data['hostname'] + hosts['hostname'] = conf.return_value("system host-name") + + # This may happen if the config is not loaded yet, + # e.g. if run by cloud-init + if not hosts['hostname']: + hosts['hostname'] = default_config_data['hostname'] if conf.exists("system domain-name"): hosts['domain_name'] = conf.return_value("system domain-name") @@ -62,8 +62,7 @@ def get_config(conf): for search in conf.return_values("system domain-search domain"): hosts['domain_search'].append(search) - if conf.exists("system name-server"): - hosts['nameserver'] = conf.return_values("system name-server") + hosts['nameserver'] = conf.return_values("system name-server") hosts['nameservers_dhcp_interfaces'] = conf.return_values("system name-servers-dhcp") -- cgit v1.2.3 From 469884f4f4f7977085db54d1ce6ad6842252660e Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Thu, 11 Jun 2020 09:06:02 +0200 Subject: host_name: T2486: configure vyos-hostsd Removes and adds all required settings. --- src/conf_mode/host_name.py | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py index 6cefab2fd..0ca7011f4 100755 --- a/src/conf_mode/host_name.py +++ b/src/conf_mode/host_name.py @@ -45,6 +45,8 @@ default_config_data = { 'static_host_mapping': {} } +hostsd_tag = 'system' + def get_config(conf): hosts = copy.deepcopy(default_config_data) @@ -118,24 +120,32 @@ def apply(config): return None ## Send the updated data to vyos-hostsd + try: + hc = vyos.hostsd_client.Client() - # vyos-hostsd uses "tags" to identify data sources - tag = "static" + hc.set_host_name(config['hostname'], config['domain_name']) - try: - client = vyos.hostsd_client.Client() + hc.delete_search_domains([hostsd_tag]) + if config['domain_search']: + hc.add_search_domains({hostsd_tag: config['domain_search']}) + + hc.delete_name_servers([hostsd_tag]) + if config['nameserver']: + hc.add_name_servers({hostsd_tag: config['nameserver']}) - # Check if disable-dhcp-nameservers is configured, and if yes - delete DNS servers added by DHCP - if config['no_dhcp_ns']: - client.delete_name_servers('dhcp-.+') + # add our own tag's (system) nameservers and search to resolv.conf + hc.delete_name_server_tags_system(hc.get_name_server_tags_system()) + hc.add_name_server_tags_system([hostsd_tag]) - client.set_host_name(config['hostname'], config['domain_name'], config['domain_search']) + # this will add the dhcp client nameservers to resolv.conf + for intf in config['nameservers_dhcp_interfaces']: + hc.add_name_server_tags_system([f'dhcp-{intf}', f'dhcpv6-{intf}']) - client.delete_name_servers(tag) - client.add_name_servers(tag, config['nameserver']) + hc.delete_hosts([hostsd_tag]) + if config['static_host_mapping']: + hc.add_hosts({hostsd_tag: config['static_host_mapping']}) - client.delete_hosts(tag) - client.add_hosts(tag, config['static_host_mapping']) + hc.apply() except vyos.hostsd_client.VyOSHostsdError as e: raise ConfigError(str(e)) -- cgit v1.2.3 From 7000385c68b5816867650781a5d8a87ce90f52aa Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Thu, 11 Jun 2020 09:07:06 +0200 Subject: host_name: T2486: remove pdns-recursor restart It shouldn't be required, if necessary it should be added to vyos-hostsd apply command. --- src/conf_mode/host_name.py | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py index 0ca7011f4..3e301477d 100755 --- a/src/conf_mode/host_name.py +++ b/src/conf_mode/host_name.py @@ -167,18 +167,6 @@ def apply(config): if process_named_running('snmpd'): call('systemctl restart snmpd.service') - # restart pdns if it is used - we check for the control dir to not raise - # an exception on system startup - # - # File "/usr/lib/python3/dist-packages/vyos/configsession.py", line 128, in __run_command - # raise ConfigSessionError(output) - # vyos.configsession.ConfigSessionError: [ system domain-name vyos.io ] - # Fatal: Unable to generate local temporary file in directory '/run/powerdns': No such file or directory - if os.path.isdir('/run/powerdns'): - ret = run('/usr/bin/rec_control --socket-dir=/run/powerdns ping') - if ret == 0: - call('systemctl restart pdns-recursor.service') - return None -- cgit v1.2.3