From bae780843ef26da1d0876086205cda9f590e9c01 Mon Sep 17 00:00:00 2001 From: Antonio Torres Date: Tue, 24 Jun 2025 13:41:17 +0200 Subject: [PATCH] dns: disable all previous Unbound configuration before deploying ours Previous configuration from another packages might break our Unbound setup. Rename the config files to disable them before deploying our configuration. Fixes: https://pagure.io/freeipa/issue/9814 Signed-off-by: Antonio Torres Reviewed-By: Thomas Woerner Reviewed-By: Rob Crittenden --- ipaclient/install/client.py | 29 ++++++++++++++++++++++++++--- ipaplatform/base/paths.py | 1 + ipaserver/install/bindinstance.py | 17 +++++++++++++++-- ipaserver/install/dns.py | 11 ++++++++++- 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py index 96e91268f54aecf08e0791c91811072e8d6f459f..1885e4a8d4d1ae97ee70c163d5a47bb819288065 100644 --- a/ipaclient/install/client.py +++ b/ipaclient/install/client.py @@ -1656,7 +1656,7 @@ def get_server_connection_interface(server): raise RuntimeError(msg) -def client_dns(server, hostname, options): +def client_dns(server, hostname, options, statestore): try: verify_host_resolvable(hostname) @@ -1672,12 +1672,22 @@ def client_dns(server, hostname, options): # Setup DNS over TLS if options.dns_over_tls: + fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) + statestore.backup_state("dns_over_tls", "enabled", True) + save_state(services.knownservices["unbound"], statestore) # setup and enable Unbound as resolver server_ip = str(list(dnsutil.resolve_ip_addresses(server))[0]) forward_addr = "forward-addr: %s#%s" % (server_ip, server) # module_config_iterator is commented out if DNSSEC validation is # not disabled. module_config_iterator = '' if options.no_dnssec_validation else '# ' + # backup and remove all previous Unbound configuration + for filename in os.listdir(paths.UNBOUND_CONFIG_DIR): + filepath = os.path.join(paths.UNBOUND_CONFIG_DIR, filename) + if filepath == paths.UNBOUND_CONF: + continue + fstore.backup_file(filepath) + remove_file(filepath) ipautil.copy_template_file( paths.UNBOUND_CONF_SRC, paths.UNBOUND_CONF, @@ -1710,7 +1720,6 @@ def client_dns(server, hostname, options): "search .", "nameserver 127.0.0.55\n" ] - fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) fstore.backup_file(paths.RESOLV_CONF) with open(paths.RESOLV_CONF, 'w') as f: f.write('\n'.join(cfg)) @@ -3242,7 +3251,7 @@ def _install(options, tdict): tasks.insert_ca_certs_into_systemwide_ca_store(ca_certs) if not options.on_master: - client_dns(cli_server[0], hostname, options) + client_dns(cli_server[0], hostname, options, statestore) update_ssh_keys(hostname, paths.SSH_CONFIG_DIR, options, cli_server[0]) @@ -3632,6 +3641,20 @@ def uninstall(options): except Exception: pass + # Restore unbound to its original status + if statestore.restore_state("dns_over_tls", "enabled"): + unbound = services.knownservices['unbound'] + if not statestore.restore_state('unbound', 'running'): + unbound.stop() + if not statestore.restore_state('unbound', 'enabled'): + unbound.disable() + # restore unbound config files that were removed during IPA install + remove_file(paths.UNBOUND_CONF) + for filename, fileinfo in fstore.files.items(): + if paths.UNBOUND_CONFIG_DIR in fileinfo: + fstore.restore_file( + os.path.join(paths.UNBOUND_CONFIG_DIR, filename)) + logger.info("Disabling client Kerberos and LDAP configurations") was_sssd_installed = False was_sshd_configured = False diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py index a5bca789bdb8d07b51779e28adf64c9b68892328..8b62971f98cb282a7bcbe30019d39bcdfadec7a9 100644 --- a/ipaplatform/base/paths.py +++ b/ipaplatform/base/paths.py @@ -102,6 +102,7 @@ class BasePathNamespace: NAMED_MANAGED_KEYS_DIR = "/var/named/dynamic" NAMED_CRYPTO_POLICY_FILE = None UNBOUND_CONF_SRC = '/usr/share/ipa/client/unbound.conf.template' + UNBOUND_CONFIG_DIR = "/etc/unbound/conf.d/" UNBOUND_CONF = "/etc/unbound/conf.d/zzz-ipa.conf" NSLCD_CONF = "/etc/nslcd.conf" NSS_LDAP_CONF = "/etc/nss_ldap.conf" diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py index 0cc1f1325ce0a9dbdb09f4100a1a22bc4f24924a..ea4d4bf0e8a2d189cc0e59835db2423d7ff1cfeb 100644 --- a/ipaserver/install/bindinstance.py +++ b/ipaserver/install/bindinstance.py @@ -690,6 +690,10 @@ class BindInstance(service.Service): self.reverse_zones = reverse_zones self.sstore.backup_state("dns_over_tls", "enabled", dns_over_tls) + self.sstore.backup_state("unbound", "running", + services.knownservices["unbound"].is_running()) + self.sstore.backup_state("unbound", "enabled", + services.knownservices["unbound"].is_enabled()) if not zonemgr: self.zonemgr = 'hostmaster.%s' % normalize_zone(self.domain) @@ -1382,8 +1386,17 @@ class BindInstance(service.Service): if self.sstore.restore_state("dns_over_tls", "enabled"): if not self.sstore.restore_state("dns_over_tls", "external_crt"): certmonger.stop_tracking(certfile=paths.BIND_DNS_OVER_TLS_CRT) - services.knownservices["unbound"].disable() - services.knownservices["unbound"].stop() + # only disable unbound if it was before IPA was deployed + if not self.sstore.restore_state("unbound", "enabled"): + services.knownservices["unbound"].disable() + if not self.sstore.restore_state("unbound", "running"): + services.knownservices["unbound"].stop() + # restore unbound config files that were removed during IPA install + ipautil.remove_file(paths.UNBOUND_CONF) + for filename, fileinfo in self.fstore.files.items(): + if paths.UNBOUND_CONFIG_DIR in fileinfo: + self.fstore.restore_file( + os.path.join(paths.UNBOUND_CONFIG_DIR, filename)) ipautil.remove_file(paths.NAMED_CONF_BAK) ipautil.remove_file(paths.NAMED_CUSTOM_CONF) diff --git a/ipaserver/install/dns.py b/ipaserver/install/dns.py index 0f7a3073f4de1641afb7fdfa77413b978fd23974..39c2f677b659ef578ab0f14322465e9d9f036c99 100644 --- a/ipaserver/install/dns.py +++ b/ipaserver/install/dns.py @@ -138,6 +138,16 @@ def _setup_dns_over_tls(options): # module_config_iterator is commented out if DNSSEC validation is # not disabled. module_config_iterator = '' if options.no_dnssec_validation else '# ' + + # backup and remove all previous Unbound configuration + fstore = sysrestore.FileStore(paths.SYSRESTORE) + for filename in os.listdir(paths.UNBOUND_CONFIG_DIR): + filepath = os.path.join(paths.UNBOUND_CONFIG_DIR, filename) + if filepath == paths.UNBOUND_CONF: + continue + fstore.backup_file(filepath) + ipautil.remove_file(filepath) + ipautil.copy_template_file( paths.UNBOUND_CONF_SRC, paths.UNBOUND_CONF, @@ -179,7 +189,6 @@ def _setup_dns_over_tls(options): ] nameservers = get_ipa_resolver().nameservers if not nameservers or nameservers[0] != "127.0.0.1": - fstore = sysrestore.FileStore(paths.SYSRESTORE) fstore.backup_file(paths.RESOLV_CONF) with open(paths.RESOLV_CONF, 'w') as f: f.write('\n'.join(cfg)) -- 2.50.1