FreeIPA is touted as a platform for centralized authentication/identity managment, and it fills this role very well. One thing that it does not do well is allow you to add a commercially signed certificate after the FreeIPA installation is complete. You have to either start with a commercially signed cert, or live with the self-signed cert forever. No switching sides! At least, that's what the documentation wants you to believe.

After struggling quite a bit (this process doesn't seem to be documented anywhere), I created a procedure to update FreeIPA with a signed commercial certificate post-install. This example uses a free StartSSL certificate, but the instructions should be similar for any other certificate.

Note: Replace all instances of example.com, ipa.example.com and client.example.com with your own host names.

First, stop your IPA server:

service ipa stop

Concatenate your signed cert & CA pem:

cat ~/ipa.example.com.crt ~/sub.class1.server.ca.pem > ~/ipa.example.com.pem

Make a p12 certificate:

openssl pkcs12 -export -in ~/ipa.example.com.pem -inkey ~/ipa.example.com.key -out ~/ipa.example.com.p12 -name ipa.example.com

Add the p12 to Apache's alias database:

pk12util -i ~/ipa.example.com.p12 -d /etc/httpd/alias

Install the p12 cert:

ipa-server-certinstall -w --http_pin=PASSWORD ~/ipa.example.com.p12
ipa-server-certinstall -d --dirsrv_pin=PASSWORD ~/ipa.example.com.p12

To add the new CA to the PKI db, you must first retrieve a password:

grep internal /var/lib/pki-ca/conf/password.conf
certutil -A -d /var/lib/pki-ca/alias -n 'caSigningCert cert-pki-ca' -t CT,C,C -a -i ~/sub.class1.server.ca.pem

Add the CA to Apache's alias db:

certutil -A -d /etc/httpd/alias -n 'EXAMPLE.COM IPA CA' -t CT,C,C -a -i ~/sub.class1.server.ca.pem

Add the CA to the LDAP db for your realm, but first you'll need a password:

cat /etc/dirsrv/slapd-EXAMPLE-COM/pwdfile.txt
certutil -A -d /etc/dirsrv/slapd-EXAMPLE-COM -n 'EXAMPLE.COM IPA CA' -t CT,C,C -a -i ~/sub.class1.server.ca.pem

Add the CA to the LDAP db for PKI IPA, and again you'll need a password:

cat /etc/dirsrv/slapd-PKI-IPA/pwdfile.txt
certutil -A -d /etc/dirsrv/slapd-PKI-IPA -n 'EXAMPLE.COM IPA CA' -t CT,C,C -a -i ~/sub.class1.server.ca.pem

Add the CA to the NSS db:

certutil -A -d /etc/pki/nssdb -n 'EXAMPLE.COM IPA CA' -t CT,C,C -a -i ~/sub.class1.server.ca.pem

Update the CA cert on the filesystem:

cat ~/ipa.example.com.pem > /usr/share/ipa/html/ca.crt
cp ~/sub.class1.server.ca.pem /etc/ipa/ca.crt

Start your IPA server:

service ipa start

Convert the CA to the DER format and add it to LDAP:

openssl x509 -outform DER -in ~/sub.class1.server.ca.pem -out /tmp/ipa.der
kinit admin
ldapmodify -Y GSSAPI
dn: cn=CAcert,cn=ipa,cn=etc,dc=example,dc=com
changetype: modify
replace: cacertificate;binary
cacertificate;binary:<file:///tmp/ipa.der

[press ctrl+d to save your changes]

If you have any existing clients, you will need to remove them from the realm and re-add them. This is complicated by the fact that the clients' CAs will not match the one you just installed. Once again, FreeIPA's documented process of copying the CA to the clients does not work. Here's how to do it:

On the server, for each client:

ldapmodify -Y GSSAPI
dn: fqdn=client.example.com,cn=computers,cn=accounts,dc=example,dc=com
changetype: modify
delete: userCertificate

[press ctrl+d to save your changes]

ipa del-host --updatedns client.example.com

On each client (you will be prompted to reboot after the uininstall, but you don't need to):

ipa-client-install --uninstall
ipa-client-install

That's it! Sit back and enjoy your valid, commercially signed SSL certificate and CA!