Connexer Ltd. Masthead

How to Ship Your Own Self-Signed Certificate Authority

Revision History

Revision Date Revised by Comments
0.0 20150526 RCS Initial draft


This article is copyright © 2015 Connexer Ltd.


Creative Commons License
This article is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Table of Contents

Getting Started
Setting Up
Tweaking the ca-certificates Certificate Store
Customizing the nss Package
Building the Modified Package
Provide Feedback


Have you ever had to go to the trouble of deploying a self-signed certificate authority to multiple Linux systems? It can be a real pain. Self-signed certificate authorities are quite useful, but that usefulness is somewhat offset by the complexity of deploying the CA to every user on every system in the enterprise. Microsoft Windows makes it possible to push certificate authorities to each system in an Active Directory so that applications that use the MS certificate store automatically benefit from the presence of the CA. However, on Linux systems there is no such central facility.

Many organizations which use Linux maintain their own internal package repositories for deploying custom or commercial packages to their systems. This HOWTO will cover how to customize the necessary packages to be able to deploy your self-signed CA to multiple systems via an existing package distribution infrastructure. Of course, if you lack such an infrastructure, the customized packages can always be deployed via manual methods.

Getting Started

This document assumes that you have read the Customizing Debian Packages HOWTO on this site or that you are already comfortable working with Debian source packages and building binary packages from those source packages.

Additionally, this document assumes that you are running at least Debian 8.0 (Jessie)

Setting Up

Packages in Debian and derived distributions generally obtain their notion of avaialble certificate authorities from one of two places: the ca-certificates package, or the libnss3 package. Command line tools (like wget and curl) and some alternative web browsers (like Epiphany) use the certificate authorities provided by the ca-certificates package. All of the Mozilla applications utilize the certificate authorities provided by the libnss3 package.

In order to complete the steps outlined in this HOWTO, you will need to install the ca-certificates and libnss3-tools packages, as well as have the nss source package downloaded and unpacked.

Tweaking the ca-certificates Certificate Store

Thankfully, the ca-certificates comes with a nearly trivial method for incorporating new certificate authorities so that they become accessible to any application which utilizes its certificate store.

This can be accomplished in two easy steps:

  1. Copy (or link) your certificate into /usr/local/share/ca-certificates with a .crt extension (e.g., /usr/local/share/ca-certificates/ACME.crt)
     user@host:~$ sudo cp ACME.crt /usr/local/share/ca-certificates/
     [sudo] password for user: 
     user@host:~$ ls -l /usr/local/share/ca-certificates/
     total 4
     -rw-r--r-- 1 root staff 1306 May 26 11:19 ACME.crt
  2. As root run /usr/sbin/update-ca-certificates
     user@host:~$ sudo cp /usr/sbin/update-ca-certificates
     Updating certificates in /etc/ssl/certs... 1 added, 0 removed; done.
     Running hooks in /etc/ca-certificates/update.d....
     Adding debian:ACME.pem
     user@host:~$ ls -l /etc/ssl/certs |grep ACME
     lrwxrwxrwx 1 root root     41 May 26 11:19 ACME.pem -> /usr/local/share/ca-certificates/ACME.crt
     lrwxrwxrwx 1 root root      8 May 26 11:19 c16b9d83.0 -> ACME.pem
     lrwxrwxrwx 1 root root      8 May 26 11:19 f2cd54d5.0 -> ACME.pem

These steps are trivially automatable with your system of choice (e.g., Ansible, Chef, Puppet, etc.) or even with a two line shell script, so it does not make sense to ship a custom ca-certificates package.

Additionally, if you have the ca-certificates-java package installed, then these steps will also handle updating the certificate store provided by that package.

Customizing the nss Package

Unfortunately, the steps to include your self-signed certificate authority in the libnss3 package so that it is visible to all instances of Mozilla applications are considerably more complex:

  1. Install the libnss3-tools package:
     user@host:~/nss$ sudo apt-get install libnss3-tools
     [sudo] password for user: 
     Reading package lists... Done
     Building dependency tree       
     Reading state information... Done
     The following NEW packages will be installed:
     0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
     Need to get 776 kB of archives.
     After this operation, 4029 kB of additional disk space will be used.
     Get:1 sid/main libnss3-tools amd64 2:3.19-1 [776 kB]
     Fetched 776 kB in 0s (11.2 MB/s)     
     Selecting previously unselected package libnss3-tools.
     (Reading database ... 43898 files and directories currently installed.)
     Preparing to unpack .../libnss3-tools_2%3a3.19-1_amd64.deb ...
     Unpacking libnss3-tools (2:3.19-1) ...
     Setting up libnss3-tools (2:3.19-1) ...
  2. Convert the certificate to DER format:
     user@host:~/nss$ openssl x509 -in ACME.crt -outform DER -out ACME.der
     user@host:~/nss$ ls -l ACME.*
     -rw-r--r-- 1 user users 1306 May 26 11:43 ACME.crt
     -rw-r--r-- 1 user users  922 May 26 11:50 ACME.der
  3. Download the nss source package:
     user@host:~/nss$ apt-get source nss
     Reading package lists... Done
     Building dependency tree       
     Reading state information... Done
     NOTICE: 'nss' packaging is maintained in the 'Git' version control system at:
     Need to get 6980 kB of source archives.
     Get:1 sid/main nss 2:3.19-1 (dsc) [2194 B]
     Get:2 sid/main nss 2:3.19-1 (tar) [6951 kB]
     Get:3 sid/main nss 2:3.19-1 (diff) [26.3 kB]
     Fetched 6980 kB in 26s (268 kB/s)                                              
     dpkg-source: info: extracting nss in nss-3.19
     dpkg-source: info: unpacking nss_3.19.orig.tar.gz
     dpkg-source: info: unpacking nss_3.19-1.debian.tar.xz
     dpkg-source: info: applying 38_hurd.patch
     dpkg-source: info: applying 38_kbsd.patch
     dpkg-source: info: applying 80_security_tools.patch
     dpkg-source: info: applying 85_security_load.patch
     dpkg-source: info: applying 95_add_spi+cacert_ca_certs.patch
     dpkg-source: info: applying 97_SSL_RENEGOTIATE_TRANSITIONAL.patch
  4. Change into the nss package source directory:
     user@host:~/nss$ cd nss-3.19/
  5. Create a new patch:
     user@host:~/nss/nss-3.19$ quilt new 99_add_new_ca_cert.patch
     Patch 99_add_new_ca_cert.patch is now on top
  6. Add the certdata.txt file to the patch:
     user@host:~/nss/nss-3.19$ quilt add ./nss/lib/ckfw/builtins/certdata.txt
     File ./nss/lib/ckfw/builtins/certdata.txt added to patch 99_add_new_ca_cert.patch
    The file may be in a different location depending on your version of the nss package. You can find the file with the following command: find . -name certdata.txt.
  7. Add the CA to the certdata.txt file:
     user@host:~/nss/nss-3.19$ nss-addbuiltin -n "ACME Certificate Authority" -t "C,C,C" -i ../ACME.der >>./nss/lib/ckfw/builtins/certdata.txt
  8. Confirm that the certificate was added to the file. Open ./nss/lib/ckfw/builtins/certdata.txt and look for the section at the end with the heading # Certificate "ACME Certificate Authority" (the actual header will match the string given to the -n option to the nss-addbuiltin command.
  9. Refresh the patch:
     user@host:~/nss/nss-3.19$ quilt refresh
     Refreshed patch 99_add_new_ca_cert.patch
  10. Add a new changelog entry with a command like:
     dch -l~acme.
    (feel free to choose a different scheme for locally tweaking the version number).

Building the Modified Package

The customizations are now complete. All that remains is to build the package and deploy to the target system(s). For additional instructions on building the package, please consult the Customizing Debian Packages HOWTO on this site.

Once the customized libnss3 package is installed, any Mozilla application run by any user on that system will have the certificate authority pre-installed as a built in certificate authority. To confirm this, open Firefox or Thunderbird (or one of the unbranded versions, like Iceweasel or Icedove) and navigate to Preferences->Advanced->Certificates->View Certificates->Authorities. Look for the "ACME Certificate Authority" entry. If you had manually imported the certificate authority, it would show up as a "Software Security Device." However, since it was built in to the NSS library, it will show up as a "Builtin Object Token" instead. This allows you to deploy your own CA which you can use to issue different certificates to each internal host/service without being required to pay a public CA to issue the certificates and without having to deal with the untrusted connection warnings.

If you managed to read this whole thing, please let me know what you thought, whether it was useful, or if you have any suggestions for improvement.


- Name and Email Validation: You Are Doing It Wrong - How to Ship Your Own Self-Signed Certificate Authority - Improve the Security of Your OpenPGP Key by Using Subkeys - Redeliver the Contents of an mbox - Customizing Debian Packages - Setting up a Debian Package Repository
More useful content ...

Top of Page