mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
certupdate: update config after deployment becomes CA-ful
When a deployment gets promoted from CA-less to CA-ful other replicas still have enable_ra=False in default.conf, and do not have the ra-agent key and certificate. Enhance ipa-certupdate to detect when the deployment has become CA-ful; retrieve the ra-agent credential and update default.conf. The rationale for adding this behaviour to ipa-certupdate is that it is already necessary to use this command to update local trust stores with the new CA certificate(s). So by using ipa-certupdate we avoid introducing additional steps for administrators. It is necessary to choose a CA master to use as the ca_host. We use the first server returned by LDAP. A better heuristic might be to choose a master in the same location but this is just left as a comment unless or until the need is proven. Finally, defer the httpd service restart until after the possible update of default.conf so that the IPA API executes with the new configuration. This change also addresses the case of a CA server being removed from the topology, i.e. ipa-certupdate detects when non-CA replicas are pointing at the removed server, and chooses a new ca_host. HOW TO TEST: 1. Install a CA-less server (first server). 2. Install a CA-less replica. 3. Run 'ipa-ca-install' on first server, promoting deployment from CA-less to CA-ful. 4. Run 'ipa-certupdate' on second server. 5. Exceute 'ipa cert-show 5' on second server. Should succeed, because ra-agent credential was retrieved and default.conf updated at step #4. Fixes: https://pagure.io/freeipa/issue/7188 Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
This commit is contained in:
@@ -106,10 +106,17 @@ def run_with_args(api):
|
||||
|
||||
server_fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
if server_fstore.has_files():
|
||||
# look up CA servers before service restarts
|
||||
resp = api.Command.server_role_find(
|
||||
role_servrole=u'CA server',
|
||||
status='enabled',
|
||||
)
|
||||
ca_servers = [server['server_server'] for server in resp['result']]
|
||||
|
||||
update_server(certs)
|
||||
|
||||
# pylint: disable=import-error,ipa-forbidden-import
|
||||
from ipaserver.install import cainstance
|
||||
from ipaserver.install import cainstance, custodiainstance
|
||||
# pylint: enable=import-error,ipa-forbidden-import
|
||||
|
||||
# Add LWCA tracking requests. Only execute if *this server*
|
||||
@@ -121,6 +128,19 @@ def run_with_args(api):
|
||||
logger.exception(
|
||||
"Failed to add lightweight CA tracking requests")
|
||||
|
||||
try:
|
||||
update_server_ra_config(
|
||||
cainstance, custodiainstance,
|
||||
api.env.enable_ra, api.env.ca_host, ca_servers,
|
||||
)
|
||||
except Exception:
|
||||
logger.exception("Failed to update RA config")
|
||||
|
||||
# update_server_ra_config possibly updated default.conf;
|
||||
# restart httpd to pick up changes.
|
||||
if services.knownservices.httpd.is_running():
|
||||
services.knownservices.httpd.restart()
|
||||
|
||||
update_client(certs)
|
||||
|
||||
|
||||
@@ -154,9 +174,6 @@ def update_server(certs):
|
||||
if services.knownservices.dirsrv.is_running():
|
||||
services.knownservices.dirsrv.restart(instance)
|
||||
|
||||
if services.knownservices.httpd.is_running():
|
||||
services.knownservices.httpd.restart()
|
||||
|
||||
criteria = {
|
||||
'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
|
||||
'cert-nickname': IPA_CA_NICKNAME,
|
||||
@@ -199,6 +216,43 @@ def update_server(certs):
|
||||
update_file(paths.CACERT_PEM, certs)
|
||||
|
||||
|
||||
def update_server_ra_config(
|
||||
cainstance, custodiainstance,
|
||||
enable_ra, ca_host, ca_servers,
|
||||
):
|
||||
"""
|
||||
After promoting a CA-less deployment to CA-ful, or after removal
|
||||
of a CA server from the topology, it may be necessary to update
|
||||
the default.conf ca_host setting on non-CA replicas.
|
||||
|
||||
"""
|
||||
if len(ca_servers) == 0:
|
||||
return # nothing to do
|
||||
|
||||
# In case ca_host setting is not valid, select a new ca_host.
|
||||
# Just choose the first server. (Choosing a server in the same
|
||||
# location might be better, but we should only incur that
|
||||
# complexity if a need is proven).
|
||||
new_ca_host = ca_servers[0]
|
||||
|
||||
if not enable_ra:
|
||||
# RA is not enabled, but deployment is CA-ful.
|
||||
# Retrieve IPA RA credential and update ipa.conf.
|
||||
cainstance.CAInstance.configure_certmonger_renewal_helpers()
|
||||
custodia = custodiainstance.CustodiaInstance(
|
||||
host_name=api.env.host,
|
||||
realm=api.env.realm,
|
||||
custodia_peer=new_ca_host,
|
||||
)
|
||||
cainstance.import_ra_key(custodia)
|
||||
cainstance.update_ipa_conf(new_ca_host)
|
||||
|
||||
elif ca_host not in ca_servers:
|
||||
# RA is enabled but ca_host is not among the deployment's
|
||||
# CA servers. Set a valid ca_host.
|
||||
cainstance.update_ipa_conf(new_ca_host)
|
||||
|
||||
|
||||
def update_file(filename, certs, mode=0o644):
|
||||
certs = (c[0] for c in certs if c[2] is not False)
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user