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

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