Blame SOURCES/0007-Don-t-always-override-the-port-in-import_included_profiles_rhbz#2022483.patch

b7b64b
From edb216849e4f47d6cae95981edf0c3fe2653fd7a Mon Sep 17 00:00:00 2001
b7b64b
From: Rob Crittenden <rcritten@redhat.com>
b7b64b
Date: Fri, 28 Jan 2022 16:46:35 -0500
b7b64b
Subject: [PATCH] Don't always override the port in import_included_profiles
b7b64b
b7b64b
I can only guess to the original purpose of this override. I
b7b64b
believe it was because this is called in the installer prior
b7b64b
to Apache being set up. The expectation was that this would
b7b64b
only be called locally. It predates the RestClient class.
b7b64b
b7b64b
RestClient will attempt to find an available service. In this
b7b64b
case, during a CA installation, the local server is not
b7b64b
considered available because it lacks an entry in
b7b64b
cn=masters. So it will never be returned as an option.
b7b64b
b7b64b
So by overriding the port to 8443 the remote connection will
b7b64b
likely fail because we don't require that the port be open.
b7b64b
b7b64b
So instead, instantiate a RestClient and see what happens.
b7b64b
b7b64b
There are several use-cases:
b7b64b
b7b64b
1. Installing an initial server. The RestClient connection
b7b64b
   should fail, so we will fall back to the override port and
b7b64b
   use the local server. If Apache happens to be running with
b7b64b
   a globally-issued certificate then the RestClient will
b7b64b
   succeed. In this case if the connected host and the local
b7b64b
   hostname are the same, override in that case as well.
b7b64b
b7b64b
2. Installing as a replica. In this case the local server should
b7b64b
   be ignored in all cases and a remote CA will be picked with
b7b64b
   no override done.
b7b64b
b7b64b
3. Switching from CA-less to CA-ful. The web server will be
b7b64b
   trusted but the RestClient login will fail with a 404. Fall
b7b64b
   back to the override port in this case.
b7b64b
b7b64b
The motivation for this is trying to install an EL 8.x replica
b7b64b
against an EL 7.9 server. 8.5+ includes the ACME service and
b7b64b
a new profile is needed which doesn't exist in 7. This was
b7b64b
failing because the RestClient determined that the local server
b7b64b
wasn't running a CA so tried the remote one (7.9) on the override
b7b64b
port 8443. Since this port isn't open: failure.
b7b64b
b7b64b
Chances are that adding the profile is still going to fail
b7b64b
because again, 7.9 lacks ACME capabilities, but it will fail in
b7b64b
a way that allows the installation to continue.
b7b64b
b7b64b
I suspect that all of the overrides can similarly handled, or
b7b64b
handled directly within the RestClient class, but for the sake
b7b64b
of "do no harm" I'm only changing this instance for now.
b7b64b
b7b64b
https://pagure.io/freeipa/issue/9100
b7b64b
b7b64b
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
b7b64b
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
b7b64b
---
b7b64b
 ipaserver/install/cainstance.py | 30 +++++++++++++++++++++++++++++-
b7b64b
 1 file changed, 29 insertions(+), 1 deletion(-)
b7b64b
b7b64b
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
b7b64b
index 8c8bf1b3a..ad206aad4 100644
b7b64b
--- a/ipaserver/install/cainstance.py
b7b64b
+++ b/ipaserver/install/cainstance.py
b7b64b
@@ -1953,7 +1953,35 @@ def import_included_profiles():
b7b64b
         cn=['certprofiles'],
b7b64b
     )
b7b64b
 
b7b64b
-    api.Backend.ra_certprofile.override_port = 8443
b7b64b
+    # At this point Apache may or may not be running with a valid
b7b64b
+    # certificate. The local server is not yet recognized as a full
b7b64b
+    # CA yet so it isn't discoverable. So try to do some detection
b7b64b
+    # on what port to use, 443 (remote) or 8443 (local) for importing
b7b64b
+    # the profiles.
b7b64b
+    #
b7b64b
+    # api.Backend.ra_certprofile invokes the RestClient class
b7b64b
+    # which will discover and login to the CA REST API. We can
b7b64b
+    # use this information to detect where to import the profiles.
b7b64b
+    #
b7b64b
+    # If the login is successful (e.g. doesn't raise an exception)
b7b64b
+    # and it returns our hostname (it prefers the local host) then
b7b64b
+    # we override and talk locally.
b7b64b
+    #
b7b64b
+    # Otherwise a NetworkError means we can't connect on 443 (perhaps
b7b64b
+    # a firewall) or we get an HTTP error (valid TLS certificate on
b7b64b
+    # Apache but no CA, login fails with 404) so we override to the
b7b64b
+    # local server.
b7b64b
+    #
b7b64b
+    # When override port was always set to 8443 the RestClient could
b7b64b
+    # pick a remote server and since 8443 isn't in our firewall profile
b7b64b
+    # setting up a new server would fail.
b7b64b
+    try:
b7b64b
+        with api.Backend.ra_certprofile as profile_api:
b7b64b
+            if profile_api.ca_host == api.env.host:
b7b64b
+                api.Backend.ra_certprofile.override_port = 8443
b7b64b
+    except (errors.NetworkError, errors.RemoteRetrieveError) as e:
b7b64b
+        logger.debug('Overriding CA port: %s', e)
b7b64b
+        api.Backend.ra_certprofile.override_port = 8443
b7b64b
 
b7b64b
     for (profile_id, desc, store_issued) in dogtag.INCLUDED_PROFILES:
b7b64b
         dn = DN(('cn', profile_id),
b7b64b
-- 
b7b64b
2.34.1
b7b64b