Trusting your own Certificate Authority
Updated at by ospiTips on getting your own CA work with various programs and utilities. The CA certificate resides in /opt/my-first-ca/my-first-ca.crt
(PEM format) in the following examples.
Operating system CA installation on CentOS 7 and Debian/Ubuntu
I'll refer this as the OS level installation in later steps. This usually covers getting the your to CA work with most tools and software available from official repositories.
For example curl
burps out an error message when the CA cannot be recognized.
curl: (60) Peer's Certificate issuer is not recognized.
And wget
output
ERROR: cannot verify hurr-durr.my-tld's certificate, issued by ‘/C=XX/ST=Muh State/L=Muh City/O=Muh Org/CN=My First CA’:
Unable to locally verify the issuer's authority.
On CentOS 7
cp /opt/my-first-ca/my-first-ca.crt /etc/pki/ca-trust/source/anchors/
update-ca-trust extract
On Debian/Ubuntu flavors
cp /opt/my-first-ca/my-first-ca.crt /usr/local/share/ca-certificates/
update-ca-certificates
Java
When java bounces into unknown CA you might see something like this:
<surrounding square meter of stack trace>
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
</stack trace>
For recent Debian/Ubuntu and CentOS distributions the OS level installation above also updates the java keystore.
But as some applications are shipped "standalone" bundled with it's very own JVM means it usually ignores CAs installed on OS level. Combined with inability to add CAs in the software might require you to find the keystore and add your CA to it manually by using keytool
.
cd /opt/some-standalone-java-app/
# Find the cacerts file
find . -name 'cacerts'
> ./jre64/lib/security/cacerts
# import your CA into the cacerts, default password is 'changeit'
keytool -import -trustcacerts -keystore ./jre64/lib/security/cacerts -alias "My First CA" -file /opt/my-first-ca/my-first-ca.crt
# Or if you don't have JVM installed, use the keytool provided by the software
./jre64/bin/keytool -import -trustcacerts -keystore ./jre64/lib/security/cacerts -alias "My First CA" -file /opt/my-first-ca/my-first-ca.crt
NodeJS from nodesource repositories on CentOS 7
Nodejs smashing itself against unknown CA.
{ Error: unable to verify the first certificate
at TLSSocket.<anonymous> (_tls_wrap.js:1103:38)
at emitNone (events.js:106:13)
at TLSSocket.emit (events.js:208:7)
at TLSSocket._finishInit (_tls_wrap.js:637:8)
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:467:38) code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' }
Version 8.9.4 (at the time of writing) of nodejs ships with it's very own CAs but you can specify NODE_EXTRA_CA_CERTS environment variable to pass a file containing additional certificates. Using the ca bundle file created by the OS level installation causes a duplicate entry warning as node's own and OS ca-bundles are partially same so I'll specify the single extra CA for the env variable.
NODE_EXTRA_CA_CERTS=/opt/my-first-ca/my-first-ca.crt node my-application.js
or
NODE_EXTRA_CA_CERTS=/opt/my-first-ca/my-first-ca.crt npm install smallest
Firefox
Another application which ships with it's own CAs. Firefox has settings for CAs but you can also manipulate the nss database with certutil
which is supplied by nss-tools
on CentOS and libnss3-tools
on Debian.
# Find the NSS database from the depths of .mozilla directory
find ~/.mozilla -name 'cert8.db'
> .mozilla/firefox/7rbrb6cb.default/cert8.db
# Add your certificate as CA with trust args "C,," meaning the CA is used for validating SSL/TLS but not for email or object signing (software).
certutil -A -n "My First CA" -d ~/.mozilla/firefox/7rbrb6cb.default -t C,, -a -i /opt/my-first-ca/my-first-ca.crt
Chromium / Chrome on Ubuntu
Chrome doesn't use the OS installed CAs but rather ships with it's own CAs and adds certificates found in ~/.pki/nssdb
on top of them. Use GUI or certutil
in your home directory.
certutil -A -n "My First CA" -d .pki/nssdb -t C,, -a -i /opt/my-first-ca/my-first-ca.crt
> certutil: function failed: SEC_ERROR_LEGACY_DATABASE: The certificate/key database is in an old, unsupported format.
# Error above indicates the NSS database is in SQLite format so the -d switch has to be prefixed with "sql:"
certutil -A -n "My First CA" -d sql:.pki/nssdb -t C,, -a -i /opt/my-first-ca/my-first-ca.crt
Docker alpine
A simple Dockerfile with CA installation. curl
is installed for testing purposes.
FROM alpine:latest
RUN apk add --update --no-cache ca-certificates curl
COPY my-first-ca.crt /usr/local/share/ca-certificates/my-first-ca.crt
RUN update-ca-certificates
RUN curl https://site-signed-with-my-own-ca.herpderp.my-own-tld