From 2092220634ffac8235abe2de5b3ad34c71a617f2 Mon Sep 17 00:00:00 2001 From: Thomas Woerner <twoerner@redhat.com> Date: Fri, 21 Jun 2019 12:24:10 +0200 Subject: [PATCH] ipareplica: Make sure that certmonger picks the right master This is related to freeipa#0f31564b35aac250456233f98730811560eda664 During ipa-replica-install, http installation first creates a service principal for http/hostname (locally on the soon-to-be-replica), then waits for this entry to be replicated on the master picked for the install. In a later step, the installer requests a certificate for HTTPd. The local certmonger first tries the master defined in xmlrpc_uri (which is pointing to the soon-to-be-replica), but fails because the service is not up yet. Then certmonger tries to find a master by using the DNS and looking for a ldap service. This step can pick a different master, where the principal entry has not always be replicated yet. As the certificate request adds the principal if it does not exist, we can end by re-creating the principal and have a replication conflict. The replication conflict later causes kerberos issues, preventing from installing a new replica. The proposed fix forces xmlrpc_uri to point to the same master as the one picked for the installation, in order to make sure that the master already contains the principal entry. https://pagure.io/freeipa/issue/7041 --- .../library/ipareplica_create_ipa_conf.py | 7 +- roles/ipareplica/library/ipareplica_test.py | 34 ++++--- roles/ipareplica/tasks/install.yml | 93 +++++++++++++++++++ 3 files changed, 121 insertions(+), 13 deletions(-) diff --git a/roles/ipareplica/library/ipareplica_create_ipa_conf.py b/roles/ipareplica/library/ipareplica_create_ipa_conf.py index 26a9a070..e46421a5 100644 --- a/roles/ipareplica/library/ipareplica_create_ipa_conf.py +++ b/roles/ipareplica/library/ipareplica_create_ipa_conf.py @@ -172,6 +172,7 @@ def main(): ### additional ### server=dict(required=True), config_master_host_name=dict(required=True), + config_ca_host_name=dict(required=True), ccache=dict(required=True), installer_ccache=dict(required=True), _ca_enabled=dict(required=False, type='bool'), @@ -183,6 +184,7 @@ def main(): _add_to_ipaservers = dict(required=True, type='bool'), _ca_subject=dict(required=True), _subject_base=dict(required=True), + master=dict(required=False, default=None), dirman_password=dict(required=True, no_log=True), ), @@ -227,6 +229,7 @@ def main(): # '_hostname_overridden') options.server = ansible_module.params.get('server') master_host_name = ansible_module.params.get('config_master_host_name') + ca_host_name = ansible_module.params.get('config_ca_host_name') ccache = ansible_module.params.get('ccache') os.environ['KRB5CCNAME'] = ccache #os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache') @@ -246,6 +249,7 @@ def main(): options._ca_subject = ansible_module.params.get('_ca_subject') options._subject_base = ansible_module.params.get('_subject_base') + master = ansible_module.params.get('master') dirman_password = ansible_module.params.get('dirman_password') @@ -267,6 +271,7 @@ def main(): config = gen_ReplicaConfig() config.subject_base = options.subject_base config.dirman_password = dirman_password + config.ca_host_name = ca_host_name remote_api = gen_remote_api(master_host_name, paths.ETC_IPA) installer._remote_api = remote_api @@ -284,7 +289,7 @@ def main(): # successful uninstallation # The configuration creation has to be here otherwise previous call # To config certmonger would try to connect to local server - create_ipa_conf(fstore, config, ca_enabled) + create_ipa_conf(fstore, config, ca_enabled, master) # done # diff --git a/roles/ipareplica/library/ipareplica_test.py b/roles/ipareplica/library/ipareplica_test.py index 41975c05..7c6f6e90 100644 --- a/roles/ipareplica/library/ipareplica_test.py +++ b/roles/ipareplica/library/ipareplica_test.py @@ -179,6 +179,14 @@ def main(): ansible_module.fail_json( msg="Hidden replica is not supported in this version.") + # We need to point to the master in ipa default conf when certmonger + # asks for HTTP certificate in newer ipa versions. In these versions + # create_ipa_conf has the additional master argument. + change_master_for_certmonger = False + argspec = inspect.getargspec(create_ipa_conf) + if "master" in argspec.args: + change_master_for_certmonger = True + # From ipa installer classes # pkinit is not supported on DL0, don't allow related options @@ -332,18 +340,20 @@ def main(): # done # - ansible_module.exit_json(changed=False, - ipa_python_version=IPA_PYTHON_VERSION, - ### basic ### - domain=options.domain_name, - realm=options.realm_name, - hostname=options.host_name, - ### server ### - setup_adtrust=options.setup_adtrust, - setup_kra=options.setup_kra, - server=options.server, - ### additional ### - client_enrolled=client_enrolled, + ansible_module.exit_json( + changed=False, + ipa_python_version=IPA_PYTHON_VERSION, + ### basic ### + domain=options.domain_name, + realm=options.realm_name, + hostname=options.host_name, + ### server ### + setup_adtrust=options.setup_adtrust, + setup_kra=options.setup_kra, + server=options.server, + ### additional ### + client_enrolled=client_enrolled, + change_master_for_certmonger=change_master_for_certmonger, ) if __name__ == '__main__': diff --git a/roles/ipareplica/tasks/install.yml b/roles/ipareplica/tasks/install.yml index 3f8bc6d1..1bb89dcb 100644 --- a/roles/ipareplica/tasks/install.yml +++ b/roles/ipareplica/tasks/install.yml @@ -314,6 +314,7 @@ server: "{{ result_ipareplica_test.server }}" config_master_host_name: "{{ result_ipareplica_install_ca_certs.config_master_host_name }}" + config_ca_host_name: "{{ result_ipareplica_prepare.config_ca_host_name }}" ccache: "{{ result_ipareplica_prepare.ccache }}" installer_ccache: "{{ result_ipareplica_prepare.installer_ccache }}" _ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}" @@ -343,6 +344,54 @@ _pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}" _top_dir: "{{ result_ipareplica_prepare._top_dir }}" + # We need to point to the master in ipa default conf when certmonger + # asks for HTTP certificate in newer ipa versions. In these versions + # create_ipa_conf has the additional master argument. + - name: Install - Create override IPA conf + ipareplica_create_ipa_conf: + ### basic ### + dm_password: "{{ ipadm_password | default(omit) }}" + password: "{{ ipaadmin_password | default(omit) }}" + ip_addresses: "{{ ipareplica_ip_addresses | default([]) }}" + domain: "{{ result_ipareplica_test.domain }}" + realm: "{{ result_ipareplica_test.realm }}" + hostname: "{{ result_ipareplica_test.hostname }}" + ca_cert_files: "{{ ipareplica_ca_cert_files | default([]) }}" + no_host_dns: "{{ ipareplica_no_host_dns }}" + ### replica ### + setup_adtrust: "{{ result_ipareplica_test.setup_adtrust }}" + setup_kra: "{{ result_ipareplica_test.setup_kra }}" + setup_dns: "{{ ipareplica_setup_dns }}" + ### ssl certificate ### + dirsrv_cert_files: "{{ ipareplica_dirsrv_cert_files | default([]) }}" + ### client ### + force_join: "{{ ipaclient_force_join }}" + ### ad trust ### + netbios_name: "{{ ipareplica_netbios_name | default(omit) }}" + rid_base: "{{ ipareplica_rid_base | default(omit) }}" + secondary_rid_base: "{{ ipareplica_secondary_rid_base | default(omit) }}" + ### additional ### + server: "{{ result_ipareplica_test.server }}" + config_master_host_name: + "{{ result_ipareplica_install_ca_certs.config_master_host_name }}" + config_ca_host_name: "{{ result_ipareplica_prepare.config_ca_host_name }}" + ccache: "{{ result_ipareplica_prepare.ccache }}" + installer_ccache: "{{ result_ipareplica_prepare.installer_ccache }}" + _ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}" + _kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}" + _dirsrv_pkcs12_info: "{{ result_ipareplica_prepare._dirsrv_pkcs12_info }}" + _http_pkcs12_info: "{{ result_ipareplica_prepare._http_pkcs12_info }}" + _pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}" + subject_base: "{{ result_ipareplica_prepare.subject_base }}" + _top_dir: "{{ result_ipareplica_prepare._top_dir }}" + _add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}" + _ca_subject: "{{ result_ipareplica_prepare._ca_subject }}" + _subject_base: "{{ result_ipareplica_prepare._subject_base }}" + dirman_password: "{{ ipareplica_dirman_password }}" + master: + "{{ result_ipareplica_install_ca_certs.config_master_host_name }}" + when: result_ipareplica_test.change_master_for_certmonger + - name: Install - DS enable SSL ipareplica_ds_enable_ssl: ### server ### @@ -383,6 +432,50 @@ _top_dir: "{{ result_ipareplica_prepare._top_dir }}" dirman_password: "{{ ipareplica_dirman_password }}" + # Need to point back to ourself after the cert for HTTP is obtained + - name: Install - Create original IPA conf again + ipareplica_create_ipa_conf: + ### basic ### + dm_password: "{{ ipadm_password | default(omit) }}" + password: "{{ ipaadmin_password | default(omit) }}" + ip_addresses: "{{ ipareplica_ip_addresses | default([]) }}" + domain: "{{ result_ipareplica_test.domain }}" + realm: "{{ result_ipareplica_test.realm }}" + hostname: "{{ result_ipareplica_test.hostname }}" + ca_cert_files: "{{ ipareplica_ca_cert_files | default([]) }}" + no_host_dns: "{{ ipareplica_no_host_dns }}" + ### replica ### + setup_adtrust: "{{ result_ipareplica_test.setup_adtrust }}" + setup_kra: "{{ result_ipareplica_test.setup_kra }}" + setup_dns: "{{ ipareplica_setup_dns }}" + ### ssl certificate ### + dirsrv_cert_files: "{{ ipareplica_dirsrv_cert_files | default([]) }}" + ### client ### + force_join: "{{ ipaclient_force_join }}" + ### ad trust ### + netbios_name: "{{ ipareplica_netbios_name | default(omit) }}" + rid_base: "{{ ipareplica_rid_base | default(omit) }}" + secondary_rid_base: "{{ ipareplica_secondary_rid_base | default(omit) }}" + ### additional ### + server: "{{ result_ipareplica_test.server }}" + config_master_host_name: + "{{ result_ipareplica_install_ca_certs.config_master_host_name }}" + config_ca_host_name: "{{ result_ipareplica_prepare.config_ca_host_name }}" + ccache: "{{ result_ipareplica_prepare.ccache }}" + installer_ccache: "{{ result_ipareplica_prepare.installer_ccache }}" + _ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}" + _kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}" + _dirsrv_pkcs12_info: "{{ result_ipareplica_prepare._dirsrv_pkcs12_info }}" + _http_pkcs12_info: "{{ result_ipareplica_prepare._http_pkcs12_info }}" + _pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}" + subject_base: "{{ result_ipareplica_prepare.subject_base }}" + _top_dir: "{{ result_ipareplica_prepare._top_dir }}" + _add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}" + _ca_subject: "{{ result_ipareplica_prepare._ca_subject }}" + _subject_base: "{{ result_ipareplica_prepare._subject_base }}" + dirman_password: "{{ ipareplica_dirman_password }}" + when: result_ipareplica_test.change_master_for_certmonger + - name: Install - Setup otpd ipareplica_setup_otpd: ### server ### -- GitLab