How do I manually renew Identity Management (IPA) certificates on RHEL6 after they have expired? (Master IPA Server)
Environment
- Red Hat Enterprise Linux 6
- Red Hat Identity Management (IPA) v3
Issue
In normal operation it’s expected that renewal of IPA subsystem certificates is working smoothly starting with Red Hat Enterprise Linux 6.4 . Unfortunately in reality there are sometimes issues to renew those certificates and a manual recovery is necessary in case certificates are already expired.
Resolution
DISCLAIMERS AND WARNINGS
This procedure was tested and has been verified to work. However, it is a complicated and potentially error-prone procedure, so please do not hesitate to contact Red Hat Technical Support for assistance if you have any questions or concerns.
This procedure needs to be run on an IPA Master with an embedded CA. Separate instructions for renewing IPA certificates on IPA Replica servers can be found here. For RHEL7 instructions, please visit this page.
CAUTION
BE SURE TO CREATE BACKUPS OF THE FOLLOWING DIRECTORIES AND FILES BEFORE BEGINNING.
- /etc/dirsrv/slapd-REALM/*.db
- /etc/dirsrv/slapd-PKI-IPA/*.db
- /etc/httpd/alias
- /etc/pki-ca/CS.cfg
- /var/lib/certmonger
- /var/lib/pki-ca/alias
PROCESS
Step1: List certificates to confirm tracking
- Run the command
getcert list. Use the output from the above command to confirm that a total of 8 certificates are being tracked for renewal and if there are, skip to Step 2.
Hint - the first line of output from the getcert list command will indicate the number of certificates being tracked:
Number of certificates and requests being tracked: 8.
-
If less than 8 certificates are being tracked, run the following commands to add tracking for the remainder of the certificates and then proceed to Step 2 (note that IPA v3 servers normally already have tracking in place for all 8 certificates):
-
Obtain INTERNAL PIN to access the NSS database(used in the below
getcert start-trackingcommands):
# grep 'internal=' /var/lib/pki-ca/conf/password.conf
- Add tracking:
# getcert start-tracking -d /var/lib/pki-ca/alias -n "auditSigningCert cert-pki-ca" -c dogtag-ipa-renew-agent -P <<internal PIN>> -B /usr/lib64/ipa/certmonger/stop_pkicad -C '/usr/lib64/ipa/certmonger/renew_ca_cert "auditSigningCert cert-pki-ca"'
# getcert start-tracking -d /var/lib/pki-ca/alias -n "ocspSigningCert cert-pki-ca" -c dogtag-ipa-renew-agent -P <<internal PIN>> -B /usr/lib64/ipa/certmonger/stop_pkicad -C '/usr/lib64/ipa/certmonger/renew_ca_cert "ocspSigningCert cert-pki-ca"'
# getcert start-tracking -d /var/lib/pki-ca/alias -n "subsystemCert cert-pki-ca" -c dogtag-ipa-renew-agent -P <<internal PIN>> -B /usr/lib64/ipa/certmonger/stop_pkicad -C '/usr/lib64/ipa/certmonger/renew_ca_cert "subsystemCert cert-pki-ca"'
# getcert start-tracking -d /var/lib/pki-ca/alias -n "Server-Cert cert-pki-ca" -c dogtag-ipa-renew-agent -P <<internal PIN>> -C '/usr/lib64/ipa/certmonger/restart_dirsrv "<<LDAP Domain Name>>"'
# getcert start-tracking -d /etc/httpd/alias -n ipaCert -c dogtag-ipa-renew-agent -p /etc/httpd/alias/pwdfile.txt -C /usr/lib64/ipa/certmonger/restart_httpd
- Here is an example:
# grep 'internal=' /var/lib/pki-ca/conf/password.conf
internal=318909843122
# getcert start-tracking -d /var/lib/pki-ca/alias -n "auditSigningCert cert-pki-ca" -c dogtag-ipa-renew-agent -P 318909843122 -B /usr/lib64/ipa/certmonger/stop_pkicad -C '/usr/lib64/ipa/certmonger/renew_ca_cert "auditSigningCert cert-pki-ca"'
# getcert start-tracking -d /var/lib/pki-ca/alias -n "ocspSigningCert cert-pki-ca" -c dogtag-ipa-renew-agent -P 318909843122 -B /usr/lib64/ipa/certmonger/stop_pkicad -C '/usr/lib64/ipa/certmonger/renew_ca_cert "ocspSigningCert cert-pki-ca"'
# getcert start-tracking -d /var/lib/pki-ca/alias -n "subsystemCert cert-pki-ca" -c dogtag-ipa-renew-agent -P 318909843122 -B /usr/lib64/ipa/certmonger/stop_pkicad -C '/usr/lib64/ipa/certmonger/renew_ca_cert "subsystemCert cert-pki-ca"'
# getcert start-tracking -d /var/lib/pki-ca/alias -n "Server-Cert cert-pki-ca" -c dogtag-ipa-renew-agent -P 318909843122 -C '/usr/lib64/ipa/certmonger/restart_dirsrv HG-EXAMPLE-COM'
# getcert start-tracking -d /etc/httpd/alias -n ipaCert -c dogtag-ipa-renew-agent -p /etc/httpd/alias/pwdfile.txt -C /usr/lib64/ipa/certmonger/restart_httpd
- Run the
getcert listcommand again to confirm that 8 certificates are now being tracked.
Step 2: Determine when the certificates were last valid
- In order for this to work, you will need to set the system clock back to a date and time when the certificates were all still valid. First, we need to stop the NTP service:
# /sbin/service ntpd stop
- To find out when the certificates were still valid, run the following command:
# for nickname in "auditSigningCert cert-pki-ca" "ocspSigningCert cert-pki-ca" "subsystemCert cert-pki-ca" "Server-Cert cert-pki-ca"
do
echo $nickname
certutil -L -d /var/lib/pki-ca/alias -n "${nickname}" | grep -i after
done
- This tells us how far to set the system clock back in time.
Step 3: Revert the system clock
- Now it's time to set the system clock back to when the certificates were valid. We recommend setting the date back at least 24 hours prior to the expiration date of the earliest expiring certificate from Step 2. For example, if your certificate expired on 10-30-2017 at 10:26, use the following command:
# date 102910262017
Step 4: Renew the certificates
- With the system clock now set back in time to allow the expired certificates to be valid, we need to force renewal on all of the certificates. Restart the certmonger service to resubmit renewal requests for the expired certificates:
# service certmonger restart
- This will renew the CA subsystem certificates, but the SSL server certificates for the Apache and 389 Directory Server services will have failed to renew. We need to do a little more work to get these certificates renewed so that the IPA CA will be fully operational. Running the
getcert listcommand again should confirm that these certificates still need to be updated.
Step 5: Verify and fix CA subsystem certificate trust permissions
- The trust attributes of the internal CA subsystem certificates should be set as in the below example (note that the ordering of the certificates may differ - what is important is that the trust attributes are correct). Pass the list ('-L') option to the
certutilcommand to display the attributes that are currently set:
# certutil -d /var/lib/pki-ca/alias -L
Certificate Nickname Trust Attributes SSL,S/MIME,JAR/XPI
ocspSigningCert cert-pki-ca u,u,u
subsystemCert cert-pki-ca u,u,u
caSigningCert cert-pki-ca CTu,Cu,Cu
Server-Cert cert-pki-ca u,u,u
auditSigningCert cert-pki-ca u,u,Pu
Note that the CA subsystem will NOT run correctly if the trust attributes of its internal certificates are incorrect.
- If the trust attributes for each certificate are correct, proceed to the next step. If not, set the correct trust attributes with the following command:
# certutil -M -n "<Certificate Nickname>" -d /var/lib/pki-ca/alias -t <Trust attributes>
- For example, to correct the trust attributes for the
auditSigningCert cert-pki-cacertificate, use the following command:
# certutil -M -n "auditSigningCert cert-pki-ca" -d /var/lib/pki-ca/alias -t u,u,Pu
- Repeat the above certutil command to correct any other certificates that have incorrect attributes set.
Step 6: Update subsystem certificate blobs in the IPA CA configuration file
-
The IPA CA configuration file contains Base64-encoded copies of the CA subsystem certificates. You'll need to confirm that the configuration file contains the current certificates and update as needed.
-
First, extract the individual CA subsystem certificates to single line text files in the /tmp directory:
# for nickname in "auditSigningCert cert-pki-ca" "ocspSigningCert cert-pki-ca" "subsystemCert cert-pki-ca" "Server-Cert cert-pki-ca"; do certutil -L -d /var/lib/pki-ca/alias -n "${nickname}" -a | sed -rn '/^-----BEGIN CERTIFICATE-----$/{:1;n;/^-----END CERTIFICATE-----$/b2;H;b1};:2;${x;s/\s//g;p}' > /tmp/"${nickname}.pem"; done
- Next, review the file
/etc/pki-ca/CS.cfgand find the blobs for the CA subsystem certificates by their nicknames. Here are the nicknames and values:
| nickname | value |
|---|---|
| auditSigningCert cert-pki-ca | ca.audit_signing.cert |
| ocspSigningCert cert-pki-ca | ca.ocsp_signing.cert |
| subsystemCert cert-pki-ca | ca.subsystem.cert |
| Server-Cert cert-pki-ca | ca.sslserver.cert |
-
Compare the certificate blobs in CS.cfg with the respective copies that you extracted to /tmp earlier; they should match and if so, you can delete the single line text files that you created in /tmp and proceed to the next step.
-
If they do NOT match. Stop the CA service:
# service pki-cad stop
-
Edit
/etc/pki-ca/CS.cfg, find the certificate entry that needs to be updated and replace the blobs with the copies that you extracted to single-line files in /tmp. Be sure to back up /etc/pki-ca/CS.cfg' before editing it! A corrupted copy of this file will cause the CA to fail to start. -
Restart the CA and verify that it is running:
# service pki-cad start
# service pki-cad status
Step 7: Test CA operation
- To test the operation of the CA, use the following command:
# curl --cacert /etc/ipa/ca.crt -v https://`hostname`:9444/ca/ee/ca/getCertChain
- You should receive a response from the CA similar to the following example:
About to connect() to ipaserver-1.example.com port 9444 (#0)
Trying 192.168.122.137... connected
Connected to ipaserver-1.example.com (192.168.122.137) port 9444 (#0)
Initializing NSS with certpath: sql:/etc/pki/nssdb
CAfile: /etc/ipa/ca.crt
CApath: none
SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Server certificate:
subject: CN=ipaserver-1.example.com,O=EXAMPLE.COM
start date: Apr 14 19:11:09 2016 GMT
expire date: Apr 04 19:11:09 2018 GMT
common name: ipaserver-1.example.com
issuer: CN=Certificate Authority,O=EXAMPLE.COM
> GET /ca/ee/ca/getCertChain HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: ipaserver-1.example.com:9444
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/xml
< Content-Length: 1462
< Date: Wed, 03 Aug 2016 16:36:00 GMT
<
[...]
Step 8: Verify and update IPA agent certificate
-
The IPA agent certificate (ipaCert) is used to authenticate with the CA for certificate operations and is stored in LDAP. This entry must be stored correctly in order for communication with the CA to occur.
-
Start by determining the new serial number for the agent certificate:
# certutil -L -d /etc/httpd/alias -n ipaCert | grep -i serial
- Next, verify what data is stored in LDAP for this entry:
# ldapsearch -x -h localhost -p 7389 -D 'cn=directory manager' -W -b uid=ipara,ou=People,o=ipaca
- Compare the serial number for the agent certificate in the
descriptionattribute with the current one. The serial number is the 2nd number. The format of the description line is:
2;[serial number];[issuer subject];[subject]
-
If the serial numbers are identical, the entry has already been updated. Proceed to the next step.
-
If the serial numbers do NOT match, run the following commands. Extract the Base64-encoded value of the agent certificate to a single line file in /tmp:
# certutil -L -d /etc/httpd/alias -n ipaCert -a | sed -rn '/^-----BEGIN CERTIFICATE-----$/{:1;n;/^-----END CERTIFICATE-----$/b2;H;b1};:2;${x;s/\s//g;p}' > /tmp/ipaCert.pem
-
Using the
ldapmodifycommand, replace the previous serial number in the description attribute with the new one and add the updated agent certificate blob with the contents of /tmp/ipaCert.pem. -
The change will look something like the below example (do NOT include brackets around the new values):
# ldapmodify -x -h localhost -p 7389 -D 'cn=directory manager' -w password
dn: uid=ipara,ou=people,o=ipaca
changetype: modify
add: usercertificate
usercertificate:: <<PASTE NEW AGENT CERTIFICATE BLOB HERE>>
-
replace: description
description: 2;<<INSERT NEW SERIAL NUMBER HERE>>;CN=Certificate Authority,O=EXAMPLE.COM;CN=IPA RA,O=EXAMPLE.COM
^D to save and exit
# service httpd restart
Step 9: Renew Directory Server and Apache SSL server certificates
- Next we need to renew the two Directory Server server certificates and the Apache server certificate:
# ipa-getcert list | grep "Request ID"
- For each of the three Request IDs run something like this:
# ipa-getcert resubmit -i [Request ID]
Step 10: Return the system clock to the correct time and date and confirm it is now current
- To return to the present time:
# service ntpd start
# date #(confirm it is now current)
Step 11: Return services to production
- Restart the world:
# service ipa restart
- Restart certmonger:
# service certmonger restart
Step 12: Test the IPA Admin user
- Log into IPA as an administrative user:
# kinit admin
Step 13: Test IPA administrative functions
- Finally, to make sure that IPA administrative functions work correctly, run a few commands to ensure expected data is returned and that no errors are reported:
# ipa cert-show 1
# ipa user-show <userid>
# ipa service-find
# ipa sudorule-find
# ipa hostgroup-find
Root Cause
Several certificates tracked by certmonger are shown with a status of CA_UNREACHABLE:
Request ID '20111111152846':
status: CA_UNREACHABLE
ca-error: Server failed request, will retry: -504 (libcurl failed to execute the HTTP POST transaction. Peer certificate cannot be authenticated with known CA certificates).
stuck: yes
key pair storage: type=NSSDB,location='/etc/httpd/alias',nickname='Server-Cert',token='NSS Certificate DB',pinfile='/etc/httpd/alias/pwdfile.txt'
certificate: type=NSSDB,location='/etc/httpd/alias',nickname='Server-Cert',token='NSS Certificate DB'
CA: IPA
issuer: CN=Certificate Authority,O=EXAMPLE.COM
subject: CN=ipa.example.com,O=EXAMPLE.COM
expires: 2013-11-11 15:28:46 UTC
eku: id-kp-serverAuth,id-kp-clientAuth
pre-save command:
post-save command: /usr/lib64/ipa/certmonger/restart_httpd
track: yes
auto-renew: yes
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.