How to Add a Custom CA Certificate to Ubuntu for System-Wide Trust


6 views

When setting up an internal PKI infrastructure with a custom Certificate Authority (CA), you'll need to ensure all Linux clients trust your root certificate. While Ubuntu provides mechanisms for system-wide CA trust, many applications maintain their own certificate stores, which can lead to inconsistent behavior.

Here's the correct way to add your CA certificate for system-wide recognition:

# Copy the certificate to the trusted directory
sudo cp your-ca.crt /usr/local/share/ca-certificates/

# Update the CA certificate store
sudo update-ca-certificates

Check if your certificate was properly added:

# List all trusted certificates
awk -v cmd='openssl x509 -noout -subject' '/BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-certificates.crt | grep "Your CA Name"

Some applications require additional configuration:

For Java Applications

# Import into Java's keystore
sudo keytool -import -trustcacerts -alias your-ca -file your-ca.crt -keystore /usr/lib/jvm/default-java/jre/lib/security/cacerts

For Node.js Applications

// Set NODE_EXTRA_CA_CERTS environment variable
process.env.NODE_EXTRA_CA_CERTS = '/path/to/your-ca.crt';

If applications still don't recognize your CA:

  • Verify the certificate file permissions (should be world-readable)
  • Check if applications are using their own certificate bundles
  • Test with OpenSSL: openssl s_client -connect your-server:443 -CAfile /etc/ssl/certs/ca-certificates.crt

For large deployments, consider using configuration management:

# Ansible playbook example
- name: Add custom CA certificate
  hosts: all
  tasks:
    - name: Copy CA certificate
      copy:
        src: your-ca.crt
        dest: /usr/local/share/ca-certificates/your-ca.crt
        mode: 0644
    
    - name: Update CA certificates
      command: update-ca-certificates
      become: yes

Ubuntu maintains a centralized certificate store managed by the ca-certificates package. The proper way to add custom CA certificates involves more than just placing files in directories - it requires integration with the system's trust chain.

Here's the complete procedure to properly install your internal CA certificate:

# 1. Copy the certificate to the correct directory
sudo cp example.com.ca.crt /usr/local/share/ca-certificates/

# 2. Ensure proper file permissions
sudo chmod 644 /usr/local/share/ca-certificates/example.com.ca.crt

# 3. Update the CA certificates store
sudo update-ca-certificates

# 4. Verify the certificate was added
openssl crl2pkcs7 -nocrl -certfile /etc/ssl/certs/ca-certificates.crt | openssl pkcs7 -print_certs -text -noout | grep -A10 "example.com"

For specific applications that maintain their own trust stores, you may need additional steps:

# For NSS-based applications (Firefox, Chrome)
certutil -A -n "Example.com Internal CA" -t "CT,c,c" -i /usr/local/share/ca-certificates/example.com.ca.crt -d sql:/home/$USER/.pki/nssdb

# For Java applications
sudo keytool -import -trustcacerts -alias example-ca -file /usr/local/share/ca-certificates/example.com.ca.crt -keystore /usr/lib/jvm/java-11-openjdk-amd64/lib/security/cacerts -storepass changeit

If applications still don't recognize your CA:

  • Check certificate expiration: openssl x509 -in /usr/local/share/ca-certificates/example.com.ca.crt -noout -dates
  • Verify certificate chain: openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt /usr/local/share/ca-certificates/example.com.ca.crt
  • Check application-specific trust stores

For large-scale deployments, consider using configuration management tools:

# Ansible playbook snippet
- name: Add internal CA certificate
  become: yes
  copy:
    src: files/example.com.ca.crt
    dest: /usr/local/share/ca-certificates/
    mode: '0644'
    owner: root
    group: root

- name: Update CA certificates
  become: yes
  command: update-ca-certificates