SSL/TLS certificates for websites and servers are just one component of a Chain of Trust, a fundamental tool to ensure security and data integrity of online communications. It also involves various elements, including certificate authorities, public and private keys, and digital signatures… to establish and verify the legitimacy of secure connections.

All certificates are backed up with a Certificate Authority and eventual intermediary certificated too.

Just by creating a self-signed certificate the encryption of the communication is guaranteed but it does not prevent from MITM (Main-In-The-Middle) attacks.

By generating a Certificate Authority certificate and key then, and installing the CA cert on all devices of a network, the Chain of Trust is completed!


LOCAL CHAIN OF TRUST

openssl genpkey -algorithm RSA -out local-ca.key
chmod 400 local-ca.key
openssl req -new -x509 -key local-ca.key -out local-ca.crt

Create a CSR (Certificate Signing Request) for FQDN or Hostname (e.g. domain.local):

openssl req -new -key local-ca.key -out domain.local.csr

Create the self-signed certificate for the CSR with the CA key:

openssl x509 -req -in domain.local.csr -signkey local-ca.key -out domain.local.crt

For the FQDN / Hostname certificate be trusted, the CA certificate must be installed in all hosts of the local network.

Add the CA certificate to Ubuntu/Debian:

cat /etc/ssl/certs/ca-certificates.crt | grep BEGIN | wc -l
sudo mv local-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
cat /etc/ssl/certs/ca-certificates.crt | grep BEGIN | wc -l

Add the CA certificate to RHEL/CentOS:

cat /etc/ssl/certs/ca-certificates.crt | grep BEGIN | wc -l
sudo mv local-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust
cat /etc/ssl/certs/ca-certificates.crt | grep BEGIN | wc -l

Note: the first and the last command only count how many CA certificates are already installed. The number should add up.

Now, the curl command and other applications might have no issue to trust a certificate issue by that CA.


CHAIN OF TRUST FOR PURCHASED CERTIFICATE

Some certificate vendors might require that the full chain of trust be built to work flawlessly:

  • Purchased Certificate
    • domain.com.crt
    • domain.com.key
  • CA Certificate
    • CA.crt

Virtual Host configuration on Apache (or any other webserver):

SSLCertificateFile /etc/ssl/certs/domain.com.crt
SSLCertificateKeyFile /etc/ssl/private/domain.com.key

Add the CA certificate to Ubuntu/Debian:

sudo mv CA.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates

Add the CA certificate to RHEL/CentOS:

sudo mv CA.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

CHAIN OF TRUST WITH BUNDLE CERTIFICATE

For serving the same domain above over the internet with no issue for remote clients that do not have this CA certificate installed:

SSLCertificateFile /etc/ssl/certs/domain.com.crt
SSLCertificateKeyFile /etc/ssl/private/domain.com.key
SSLCACertificateFile /etc/ssl/ca/CA.crt

Optionally, both .crt files can be combined in one:

cat /etc/ssl/certs/domain.com.crt > /etc/ssl/certs/bundle_domain.com.crt
cat /etc/ssl/ca/CA.crt >> /etc/ssl/certs/bundle_domain.com.crt

This bundle certificate will provide the clients all the resources they need to verify the purchased certificate.


BONUS

On Debian based systems, this command will wipe and re-add all CA certificates:

sudo update-ca-certificates --fresh

If needed, clear all cached certificates:

sudo rm -rf /etc/ssl/certs/*
sudo update-ca-certificates

SEE ALSO

A post about LIGHTtpd with Self-signed Cert  [Link].