From a785d0c561b8e22bd9d56739481095e07e0a7eb7 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Mon, 30 Sep 2024 13:30:46 -0400 Subject: [PATCH] Don't rely on removing the CA to uninstall the ACME depoyment There has always been a pki-server commnd acme-remove. We were not aware that it should be called prior to removing a CA. In 11.5.0 this is strongly encouraged by the PKI team. In 11.6.0 ACME is treated as a full subsystem so will be removed in the future using pkidestroy -s ACME The new class acmeinstance.ACMEInstance is introduced so its uninstallation can be handled in a similar way as the other PKI services via DogtagInstance. It is, right now, a pretty thin wrapper. We can discuss moving the ACME installation routines here at some point. It would be ok as long as we don't have to introduce another PKI restart as part of it. In PKI 11.6.0 pkidestroy has new options to ensure a clean uninstall: --remove-conf --remove-logs. Pass those options into pkidestroy calls for 11.6.0+. Clean up an additional IPA-generated file that needs to be cleaned up during uninstall: /root/kracert.p12. 11.6.0 is more sensitive to leftover files than previous versions. Fixes: https://pagure.io/freeipa/issue/9673 Fixes: https://pagure.io/freeipa/issue/9674 Signed-off-by: Rob Crittenden Reviewed-By: Alexander Bokovoy --- ipaserver/install/acmeinstance.py | 31 +++++++++++++ ipaserver/install/ca.py | 5 ++- ipaserver/install/cainstance.py | 1 + ipaserver/install/dogtaginstance.py | 44 +++++++++++++------ .../test_integration/test_uninstallation.py | 21 +++++++++ 5 files changed, 87 insertions(+), 15 deletions(-) create mode 100644 ipaserver/install/acmeinstance.py diff --git a/ipaserver/install/acmeinstance.py b/ipaserver/install/acmeinstance.py new file mode 100644 index 0000000000000000000000000000000000000000..0027c314545f384d9b6ee24b279479e5360d8bef --- /dev/null +++ b/ipaserver/install/acmeinstance.py @@ -0,0 +1,31 @@ +# +# Copyright (C) 2024 FreeIPA Contributors see COPYING for license +# + +import logging + +from ipaserver.install.dogtaginstance import DogtagInstance + +logger = logging.getLogger(__name__) + + +class ACMEInstance(DogtagInstance): + """ + ACME is deployed automatically with a CA subsystem but it is the + responsibility of IPA to uninstall the service. + + This is mostly a placeholder for the uninstaller. We can + eventually move the ACME installation routines into this class + if we want but it might result in an extra PKI restart which + would be slow. + """ + def __init__(self, realm=None, host_name=None): + super(ACMEInstance, self).__init__( + realm=realm, + subsystem="ACME", + service_desc="ACME server", + host_name=host_name + ) + + def uninstall(self): + DogtagInstance.uninstall(self) diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py index ffcb5268399ce71128fc8de5f54d433d35e99dd2..520e3fc5de1084e7c22c0cf7eaa86e1d3c421373 100644 --- a/ipaserver/install/ca.py +++ b/ipaserver/install/ca.py @@ -22,7 +22,7 @@ from ipaplatform.constants import constants from ipaserver.install import sysupgrade from ipapython.install import typing from ipapython.install.core import group, knob, extend_knob -from ipaserver.install import cainstance, bindinstance, dsinstance +from ipaserver.install import acmeinstance, cainstance, bindinstance, dsinstance from ipapython import ipautil, certdb from ipapython import ipaldap from ipapython.admintool import ScriptError @@ -715,6 +715,9 @@ def install_step_1(standalone, replica_config, options, custodia): def uninstall(): + acme = acmeinstance.ACMEInstance(api.env.realm) + acme.uninstall() + ca_instance = cainstance.CAInstance(api.env.realm) ca_instance.stop_tracking_certificates() ipautil.remove_file(paths.RA_AGENT_PEM) diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py index 5dac2c0441752e7bb569cde1fc93bc17c3128cdf..5c2c9f8b981cf5d587865f7680e2b231eae655e2 100644 --- a/ipaserver/install/cainstance.py +++ b/ipaserver/install/cainstance.py @@ -1118,6 +1118,7 @@ class CAInstance(DogtagInstance): ipautil.remove_file(paths.DOGTAG_ADMIN_P12) ipautil.remove_file(paths.CACERT_P12) + ipautil.remove_file(paths.ADMIN_CERT_PATH) def unconfigure_certmonger_renewal_guard(self): if not self.is_configured(): diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py index e89492312deb8ca20668a62fd7a2a20e2866a3fb..4b0f4d274b0c33140ed6f939f1a3fd8b75930ff9 100644 --- a/ipaserver/install/dogtaginstance.py +++ b/ipaserver/install/dogtaginstance.py @@ -304,21 +304,37 @@ class DogtagInstance(service.Service): if self.is_installed(): self.print_msg("Unconfiguring %s" % self.subsystem) - args = [paths.PKIDESTROY, - "-i", "pki-tomcat", "--force", - "-s", self.subsystem] - - # specify --log-file on PKI 11.0.0 or later - + args = [] pki_version = pki.util.Version(pki.specification_version()) - if pki_version >= pki.util.Version("11.0.0"): - timestamp = time.strftime( - "%Y%m%d%H%M%S", - time.localtime(time.time())) - log_file = os.path.join( - paths.VAR_LOG_PKI_DIR, - "pki-%s-destroy.%s.log" % (self.subsystem.lower(), timestamp)) - args.extend(["--log-file", log_file]) + if self.subsystem == "ACME": + if pki_version < pki.util.Version("11.0.0"): + return + elif ( + pki.util.Version("11.0.0") <= pki_version + <= pki.util.Version("11.5.0") + ): + args = ['pki-server', 'acme-remove'] + else: + # fall through for PKI >= 11.6.0 + pass + if not args: + args = [paths.PKIDESTROY, + "-i", "pki-tomcat", "--force", + "-s", self.subsystem] + + # specify --log-file on PKI 11.0.0 or later + + if pki_version >= pki.util.Version("11.0.0"): + timestamp = time.strftime( + "%Y%m%d%H%M%S", + time.localtime(time.time())) + log_file = os.path.join( + paths.VAR_LOG_PKI_DIR, + "pki-%s-destroy.%s.log" % + (self.subsystem.lower(), timestamp)) + args.extend(["--log-file", log_file]) + if pki_version >= pki.util.Version("11.6.0"): + args.extend(["--remove-conf", "--remove-logs"]) try: ipautil.run(args) diff --git a/ipatests/test_integration/test_uninstallation.py b/ipatests/test_integration/test_uninstallation.py index 4f8f17ce3ad8d5376ecba11442f379e5691de7f7..049c50db536ae1070f5f958e76b12a1518da0aba 100644 --- a/ipatests/test_integration/test_uninstallation.py +++ b/ipatests/test_integration/test_uninstallation.py @@ -197,6 +197,7 @@ class TestUninstallCleanup(IntegrationTest): '/var/lib/sss/pubconf/krb5.include.d/localauth_plugin', '/var/named/dynamic/managed-keys.bind', '/var/named/dynamic/managed-keys.bind.jnl', + '/var/lib/systemd/coredump/', ] leftovers = [] @@ -217,3 +218,23 @@ class TestUninstallCleanup(IntegrationTest): leftovers.append(line) assert len(leftovers) == 0 + + +class TestUninstallReinstall(IntegrationTest): + """Test install, uninstall, re-install. + + Reinstall with PKI 11.6.0 was failing + https://pagure.io/freeipa/issue/9673 + """ + + num_replicas = 0 + + @classmethod + def install(cls, mh): + tasks.install_master(cls.master, setup_dns=False) + + def test_uninstall_server(self): + tasks.uninstall_master(self.master) + + def test_reinstall_server(self): + tasks.install_master(self.master, setup_dns=False) -- 2.46.2