Skip to content

CA Installation Process

Endi S. Dewata edited this page Dec 14, 2023 · 68 revisions

Overview

This page describes the process to install CA in IPA 4.9.

Installation Process

The process is defined in CAInstance.configure_instance():

        # Determine if we are installing as an externally-signed CA and
        # what stage we're in.
        if csr_file is not None:
            self.csr_file = csr_file
            self.external = 1
        elif cert_file is not None:
            self.cert_file = cert_file
            self.cert_chain_file = cert_chain_file
            self.external = 2

        if self.clone:
            has_ra_cert = os.path.exists(paths.RA_AGENT_PEM)
        else:
            has_ra_cert = False

        if not ra_only:
            if promote:
                # Setup Database
                self.step("creating certificate server db", self.__create_ds_db)
                self.step("setting up initial replication", self.__setup_replication)
                self.step("creating ACIs for admin", self.add_ipaca_aci)
                self.step("creating installation admin user", self.setup_admin)
            self.step("configuring certificate server instance",
                      self.__spawn_instance)
            # Config file and ACL modifications require either restart or
            # offline update of Dogtag.
            self.step("stopping certificate server instance to update CS.cfg",
                      self.stop_instance)
            self.step("backing up CS.cfg", self.safe_backup_config)
            self.step("Add ipa-pki-wait-running", self.add_ipa_wait)
            self.step("secure AJP connector", self.secure_ajp_connector)
            self.step("reindex attributes", self.reindex_task)
            self.step("exporting Dogtag certificate store pin",
                      self.create_certstore_passwdfile)
            self.step("disabling nonces", self.__disable_nonce)
            self.step("set up CRL publishing", self.__enable_crl_publish)
            self.step("enable PKIX certificate path discovery and validation",
                      self.enable_pkix)
            self.step("authorizing RA to modify profiles",
                      configure_profiles_acl)
            self.step("authorizing RA to manage lightweight CAs",
                      configure_lightweight_ca_acls)
            self.step("Ensure lightweight CAs container exists",
                      ensure_lightweight_cas_container)
            self.step(
                "Ensuring backward compatibility",
                self.__dogtag10_migration)
            if promote:
                self.step("destroying installation admin user",
                          self.teardown_admin)
            # Materialize config changes and new ACLs
            self.step("starting certificate server instance",
                      self.start_instance)
            if promote:
                self.step("Finalize replication settings",
                          self.finalize_replica_config)
        # Step 1 of external is getting a CSR so we don't need to do these
        # steps until we get a cert back from the external CA.
        if self.external != 1:
            if not has_ra_cert:
                self.step("configure certmonger for renewals",
                          self.configure_certmonger_renewal_helpers)
                if not self.clone:
                    self.step("requesting RA certificate from CA", self.__request_ra_certificate)
                elif promote:
                    self.step("Importing RA key", self.__import_ra_key)
                else:
                    self.step("importing RA certificate from PKCS #12 file",
                              self.__import_ra_cert)
            if not ra_only:
                if not self.clone:
                    self.step("publishing the CA certificate",
                              self.__export_ca_chain)
                    self.step("adding RA agent as a trusted user", self.__create_ca_agent)
                self.step("configure certificate renewals", self.configure_renewal)
                self.step("Configure HTTP to proxy connections",
                          self.http_proxy)
                self.step("updating IPA configuration", update_ipa_conf)
                self.step("enabling CA instance", self.__enable_instance)
                if not promote:
                    if self.clone:
                        # DL0 workaround; see docstring of __expose_ca_in_ldap
                        self.step("exposing CA instance on LDAP",
                                  self.__expose_ca_in_ldap)

                    self.step("importing IPA certificate profiles",
                              import_included_profiles)
                    self.step("migrating certificate profiles to LDAP",
                              migrate_profiles_to_ldap)
                    self.step("adding default CA ACL", ensure_default_caacl)
                    self.step("adding 'ipa' CA entry", ensure_ipa_authority_entry)
                    if not self.clone:
                        self.step("Recording random serial number state",
                                  self.__store_random_serial_number_state)
                else:
                    # Re-import profiles in the promote case to pick up any
                    # that will only be triggered by an upgrade.
                    self.step("importing IPA certificate profiles",
                              import_included_profiles)

                self.step("configuring certmonger renewal for lightweight CAs",
                          self.add_lightweight_ca_tracking_requests)
                if minimum_acme_support():
                    self.step("deploying ACME service", self.setup_acme)

        if ra_only:
            runtime = None
        else:
            runtime = 180

        try:
            self.start_creation(runtime=runtime)
        finally:
            if self.external == 1:
                # Don't remove client DB in external CA step 1
                # https://pagure.io/freeipa/issue/7742
                logger.debug("Keep pkispawn files for step 2")
            else:
                self.clean_pkispawn_files()

Creating certificate server database

This step is defined in CAInstance.__create_ds_db().

This step creates PKI database. It is needed when pkispawn option pki_ds_create_new_db is set to False.

It creates the following entries:

  • cn=ipaca,cn=ldbm database,cn=plugins,cn=config

  • cn=o\=ipaca,cn=mapping tree,cn=config

Setting up initial replication

This step is defined in CAInstance.__setup_replication().

Creating ACIs for admin

Creating installation admin user

Configuring certificate server instance

This step is defined in CAInstance.__spawn_instance().

It creates and configures a new CA instance using pkispawn. It creates the config file with IPA specific parameters and passes it to the base class to call pkispawn.

See also:

Stopping certificate server instance to update CS.cfg

This step is defined in DogtagInstance.stop_instance().

It calls:

$ systemctl stop pki-tomcatd@pki-tomcat

Backing up CS.cfg

This step is defined in CAInstance.safe_backup_config().

It copies /var/lib/pki/pki-tomcat/conf/ca/CS.cfg into /var/lib/pki/pki-tomcat/conf/ca/CS.cfg.ipabkp.

Adding ipa-pki-wait-running

This step is defined in CAInstance.add_ipa_wait().

It adds ipa-pki-wait-running into pki-tomcatd service.

It creates /etc/systemd/system/[email protected]/ipa.conf that contains:

[Service]
Environment=LC_ALL=C.UTF-8
ExecStartPost=/usr/libexec/ipa/ipa-pki-wait-running

Then it calls systemdctl daemon-reload.

Securing AJP connector

This step is defined in DogtagInstance.secure_ajp_connector().

It updates the AJP connectors in /etc/pki/pki-tomcat/server.xml to use a password protection.

<Connector
    protocol="AJP/1.3"
    address="127.0.0.1"
    port="8009"
    redirectPort="8443"
    secret="..." />
<Connector
    protocol="AJP/1.3"
    address="::1"
    port="8009"
    redirectPort="8443"
    secret="..." />

Reindex attributes

This step is defined in DogtagInstance.reindex_task().

It reindexes ipaca entries.

pkispawn sometimes does not run its indextasks. This leads to slow unindexed filters on attributes such as description, which is used to log in with a certificate. This task explicitly reindexes attribute that should have been reindexed by CA’s indextasks.ldif.

Exporting Dogtag certificate store PIN

This step is defined in CAInstance.create_certstore_passwdfile().

This step creates /etc/pki/pki-tomcat/alias/pwdfile.txt file so that this file can be assumed and used for certutil operations.

Disabling nonces

This step is defined in CAInstance.__disable_nonce().

It sets ca.enableNonces to false in /var/lib/pki/pki-tomcat/conf/ca/CS.cfg.

Set up CRL publishing

This step is defined in CAInstance.__enable_crl_publish().

It enables file-based CRL publishing and disable LDAP publishing.

Enable PKIX certificate path discovery and validation

This step is defined in CAInstance.enable_pkix().

It sets NSS_ENABLE_PKIX_VERIFY=1 in:

  • Fedora: /etc/sysconfig/pki-tomcat

  • Debian: /etc/default/pki-tomcat

Authorizing RA to modify profiles

This step is defined in CAInstance.configure_profiles_acl().

It allows the Certificate Manager Agents group to modify profiles.

It adds the following ACL entries:

certServer.profile.configuration:read,modify:allow (read,modify) group="Certificate Manager Agents":Certificate Manager agents may modify (create/update/delete) and read profiles
certServer.ca.account:login,logout:allow (login,logout) user="anybody":Anybody can login and logout

Authorizing RA to manage lightweight CAs

It allows Certificate Manager Agents to manage lightweight CAs.

It adds the following ACL entries:

certServer.ca.authorities:list,read:allow (list,read) user="anybody":Anybody may list and read lightweight authorities
certServer.ca.authorities:create,modify:allow (create,modify) group="Administrators":Administrators may create and modify lightweight authorities
certServer.ca.authorities:delete:allow (delete) group="Administrators":Administrators may delete lightweight authorities
certServer.ca.authorities:create,modify,delete:allow (create,modify,delete) group="Certificate Manager Agents":Certificate Manager Agents may manage lightweight authorities

Ensuring lightweight CAs container exists

It checks whether the following entry exists in DS:

dn: ou=authorities,ou=ca,o=ipaca
objectClass: top
objectClass: organizationalUnit
ou: authorities

Ensuring backward compatibility

This step is defined in CAInstance.__dogtag10_migration().

Destroying installation admin user

Starting certificate server instance

This step is defined in DogtagInstance.start_instance().

It calls:

$ systemctl start pki-tomcatd@pki-tomcat

Finalizing replication settings

This step is defined in CAInstance.finalize_replica_config().

Configuring certmonger for renewals

Requesting RA certificate from CA

This step is defined in CAInstance.__request_ra_certificate().

It requests the IPA RA certificate from Dogtag.

Dogtag automatically generates an admin certificate that in a usual deployment would be used in the UI to handle administrative duties. IPA does not use this certificate except as a bootstrap to generate the RA.

To do this it bends over backwards a bit by modifying the way typical certificates are retrieved using certmonger by forcing it to call dogtag-submit directly.

Importing RA key

This step is defined in CAInstance.__import_ra_key().

Importing RA certificate from PKCS #12 file

This step is defined in CAInstance.__import_ra_cert().

This is used when setting up replication.

Cloned RAs will use the same RA agent cert as the master so we need to import from a PKCS#12 file.

Publishing the CA certificate

This step is defined in CAInstance.__export_ca_chain().

It gets the CA chain from Dogtag NSS database and writes it to /etc/ipa/ca.crt.

Adding RA agent as a trusted user

This step is defined in CAInstance.__create_ca_agent().

It creates RA agent:

dn: uid=ipara,ou=People,o=ipaca
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: cmsuser
uid: ipara
sn: ipara
cn: ipara
userType: agentType
userState: 1

assigns the RA agent certificate:

dn: uid=ipara,ou=People,o=ipaca
changetype: modify
add: userCertificate
userCertificate: <cert data>
-
add: description
description: 2;<serial number>;<issuer DN>;<subject DN>

and adds the user to the appropriate groups for accessing CA services:

dn: cn=Certificate Manager Agents,ou=groups,o=ipaca
changetype: modify
add: uniqueMember
uniqueMember: uid=ipara,ou=People,o=ipaca

dn: cn=Registration Manager Agents,ou=groups,o=ipaca
changetype: modify
add: uniqueMember
uniqueMember: uid=ipara,ou=People,o=ipaca

dn: cn=Security Domain Administrators,ou=groups,o=ipaca
changetype: modify
add: uniqueMember
uniqueMember: uid=ipara,ou=People,o=ipaca

Configure certificate renewals

Configure HTTP to proxy connections

This step is defined in DogtagInstance.http_proxy().

It updates the HTTP proxy file:

  • Fedora: /etc/httpd/conf.d/ipa-pki-proxy.conf

  • Debian: /etc/apache2/conf-enabled/ipa-pki-proxy.conf

  • SUSE: /etc/apache2/conf.d/ipa-pki-proxy.conf

Updating IPA configuration

This step is defined in CAInstance.update_ipa_conf().

It updates IPA configuration file to ensure that RA plugins are enabled and that CA host points to specified server (or localhost if ca_host=None).

Enabling CA instance

This step is defined in CAInstance.__enable_instance().

Exposing CA instance on LDAP

This step is defined in CAInstance.__expose_ca_in_ldap().

In a case when replica is created on DL0 we need to make sure that query for CA service record of this replica in LDAP will succeed in time of installation. This method is needed for sucessfull replica installation on DL0 and should be removed alongside with code for DL0.

Importing IPA certificate profiles

This step is defined in CAInstance.import_included_profiles().

Migrating certificate profiles to LDAP

This step is defined in CAInstance.migrate_profiles_to_ldap().

This must be run after switching to the LDAPProfileSubsystem and restarting the CA.

The profile might already exist, e.g. if a replica was already upgraded, so this case is ignored. New/missing profiles are imported into LDAP. Existing profiles are not modified. This means that they are neither enabled nor updated when the file on disk has been changed.

Adding default CA ACL

This step is defined in CAInstance.ensure_default_caacl().

It adds the default CA ACL if missing:

dn: cn=ca,dc=example,dc=com
objectClass: top
objectClass: nsContainer
cn: ca

dn: cn=caacls,cn=ca,dc=example,dc=com
objectClass: top
objectClass: nsContainer
cn: certprofiles  <-- bug?

Adding 'ipa' CA entry

Tihs step is defined in CAInstance.ensure_ipa_authority_entry().

It adds the IPA CA ipaCa object if missing.

This requires the "host authority" authority entry to have been created, which Dogtag will do automatically upon startup, if the ou=authorities,ou=ca,o=ipaca container exists.

Therefore, the ensure_lightweight_cas_container() function must be executed, and Dogtag restarted, before executing this function.

dn: cn=cas,cn=ca,dc=example,dc=com
objectClass: top
objectClass: nsContainer
cn: cas

dn: cn=ipa,cn=cas,cn=ca,dc=example,dc=com
objectClass: top
objectClass: ipaca
cn: ipa
description: IPA CA

Recording random serial number state

It saves the Random Serial Number (RSN) version.

This is intended to add flexibility in case RSN bumps another version in dogtag. For now we only support v3 or no randomization (0).

dn: cn=ipa,cn=cas,cn=ca,dc=example,dc=com
changetype: modify
replace: ipaCaRandomSerialNumberVersion
ipaCaRandomSerialNumberVersion: <version>

Configuring certmonger renewal for lightweight CAs

Deploying ACME service

Cleaning up pkispawn files

Clone this wiki locally