After creating a new certificate authority, manually importing the CA chain to a browser, and verifying that browsers can trust new certs signed with the intermediary, we copied the CA cert chain (pem and crt formatted) to our Ubuntu servers under the following directories:

  • /etc/ssl/certificates/
  • /usr/local/share/ca-certificates/

Once this was done however, applications on the Ubuntu machines such as wget/curl/java still do not trust connections that use the new certs. According to another post, we need to run dpkg-reconfigure -f noninteractive ca-certificates or update-ca-certificates on each machine that has the cert. Not only have these commands not worked, it would be impractical to run them against thousands of servers. We use CFEngine for configuration management, but it does not seem to have a facility for this sort of thing as far as I can tell.

Is there a way to script Ubuntu to non-interactively update the trusted CA certs in a manner that could work against thousands of machines?

up vote 5 down vote accepted

I agree with everything BillThor mentioned, but i'll add that it may be necessary to completely rebuild the certificate store, because sometimes it seems like update-ca-certificates tries too hard to be lazy, and doesn't actually update things it should.

rm -f /usr/local/share/ca-certificates/certificate.crt
# --fresh is needed to remove symlinks to no-longer-present certificates
update-ca-certificates --fresh

Also, note that once update-ca-certificates is complete, it should have symlinked the /etc/ssl/certs/*.pem files to their respective certificates in /usr/local/share/ca-certificates/ or /usr/share/ca-certificates/. As BillThor mentioned, there will also be a symlink to a file with the fingerprint as a name - it will be similar to 349f2832.0.

An ls -l can confirm this:

--snip--
lrwxrwxrwx 1 root root     72 Feb  6  2014 Security_Communication_EV_RootCA1.pem -> /usr/share/ca-certificates/mozilla/Security_Communication_EV_RootCA1.crt
lrwxrwxrwx 1 root root     69 Mar 25  2014 Security_Communication_RootCA2.pem -> /usr/share/ca-certificates/mozilla/Security_Communication_RootCA2.crt
lrwxrwxrwx 1 root root     69 Feb  6  2014 Security_Communication_Root_CA.pem -> /usr/share/ca-certificates/mozilla/Security_Communication_Root_CA.crt
lrwxrwxrwx 1 root root     61 Feb  6  2014 Sonera_Class_1_Root_CA.pem -> /usr/share/ca-certificates/mozilla/Sonera_Class_1_Root_CA.crt
--snip--

Also notice that *.crt and *.pem are the same file. This means the original .crt put in place should be in .pem format.

A .pem format file looks like this:

-----BEGIN CERTIFICATE-----
MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB
gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk
--snip--
IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy
i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ
O+7ETPTsJ3xCwnR8gooJybQDJbw=
-----END CERTIFICATE-----

You can test your certificate installation by running openssl against the cert: openssl x509 -in /etc/ssl/certs/[certname].pem -noout -text and openssl x509 -in /usr/local/share/ca-certificates/[certname].pem -noout -text (of course replacing [certname])

You should see some extensive info about your certificate, and both should match (since with a symlink they should be the same file).

If they don't match, then you should re-run update-ca-certificates --fresh

If they don't output useful info at all, then you need to check your cert and make sure it's in valid PEM format.

EDIT: BillThor mentioned this won't work for Java, but it appears as though on debian at least, Java's certificate store is also kept up to date by the update-ca-certificates tool. I'm not aware of other things on linux that use an alternative certificate store, besides perhaps Wine running an Adobe Air app.

  • 1
    I think the majority of my confusion was in relation to crt and pem being the same format. I had followed some instructions from elsewhere that looked like they were supposed to "convert" between the two, but in fact only gave me a partial chain in the same format. Naturally, the partial cert didn't do the trick. Simply renaming the chain pem file to end in .crt, placing it under /usr/local/share/ca-certificates, and running update-ca-certificates --fresh did the trick. – MrDrMcCoy Mar 17 '17 at 21:57

Tools like update-ca-certificates ensure that the certificate is linked to by a symbolic link that matches the hash value of the certificate. When deploying certificates using cfengine, I include a step to add the symbolic link after the certificate is copied. I found this simpler to define than running a program when the certificate was installed.

Java uses a cacerts file located within the installation directory. You will need to either install a new cacerts file or import the certificate into the cacerts file. Alternatively, you may be able to install a jssecacerts file next to the existing cacerts file. With either file, you need to ensure the file contains all the certificates you want to trust. This may be a sub-set of the default set. The simplest and most stable option would be to install the file in the default Java version. The certificates in cacerts are periodically updated as various certificate authorities update their public trust certificates, so you will need to maintain this file over time.

Depending on which browser you are using you may need to install the certificate as a trusted certificate into the browser's keystore which may not be either of the stores already discussed.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.