SSL/TLS certificates for websites and servers are just one component of a Chain of Trust, a fundamental concept to ensure the security and data integrity of online communications. It 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 by a Certificate Authority and optional intermediary certificates as well.
Creating a self-signed certificate guarantees encryption of the communication, but it does not protect against MITM (Man-In-The-Middle) attacks.
By generating a Certificate Authority certificate and key, then installing the CA cert on all devices in 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 a FQDN or Hostname (e.g. domain.local):
openssl req -new -key local-ca.key -out domain.local.csr
Create the 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 to be trusted, the CA certificate must be installed on all hosts in the local network.
Add the CA certificate on 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 on 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 last commands count how many CA certificates are already installed. The number should increase after the update.
The curl command and other applications should now trust certificates issued by that CA.
CHAIN OF TRUST FOR PURCHASED CERTIFICATE
Some certificate vendors require that the full chain of trust be provided to work correctly:
- Purchased Certificate
domain.com.crtdomain.com.key
- CA Certificate
CA.crt
Virtual Host configuration on Apache (or any other web server):
SSLCertificateFile /etc/ssl/certs/domain.com.crt SSLCertificateKeyFile /etc/ssl/private/domain.com.key
Add the CA certificate on Ubuntu/Debian:
sudo mv CA.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates
Add the CA certificate on RHEL/CentOS:
sudo mv CA.crt /etc/pki/ca-trust/source/anchors/ sudo update-ca-trust
CHAIN OF TRUST WITH BUNDLE CERTIFICATE
To serve the same domain over the internet without issues for remote clients that do not have the 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 into 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 provides clients with everything they need to verify the purchased certificate.
LAZY LOCALHOST SELF-SIGNED
sudo apt install libnss3-tools mkcert -y sudo mkcert --install
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].