Creating an SSL Certificate Authority (CA), signing certificates and authenticating using a client certificate

Greetings Squirrel army,

We’ve been looking into writing a quick post on SSL Certificate Authorities for quite some time, so here’s our blog post on how to get this done. We’re also going to take a look at client authentication using a certificate.

Please note that this post is based on the incredible post from the DataCenter Lords called “Creating Your Own SSL Certificate Authority (and Dumping Self Signed Certs)” – make sure to visit that one for more details on how the authentication works.

1. Create a directory that we’ll use to store our Root certificates and enter the directory

mkdir -pv /squirrel5-CA-root
cd /squirrel5-CA-root

2. Create a key for the CA – (Protip: NEVER SHARE THIS!)

openssl genrsa -out rootCA-NEVER_SHARE.key 2048

3. Use the key to create your CA certificate – this one (rootCA.pem) can be shared to the workstations you want to trust your new CA

openssl req -x509 -new -nodes -key rootCA-NEVER_SHARE.key -sha256 -days 1024 -out rootCA.pem

In the prompt that you’ll get the only line that really matters is the Common Name (CN):

"Common Name (eg, your name or your server's hostname) []"

In this example we’ll answer everything with “Enter” except the Common Name which we will name “Squirrel5-CA

4. Create a private key for one of your servers:

openssl genrsa -out server1.key 2048

5. Create a Certificate Signing Request (CSR) for your first server:

openssl req -new -key server1.key -out server1.csr

Just like above, the only line that matters here is the “Common Name” – the common name must be a FQDN or an IP address, in this example we’ll use

6. And now for the most important bit – use the rootCA-NEVER_SHARE.key to SIGN the new certificate and also tell it what CA to use the “-CA rootCA.pem” bit:

openssl x509 -req -in server1.csr -CA rootCA.pem -CAkey rootCA-NEVER_SHARE.key -CAcreateserial -out server1.crt -days 500 -sha256

For server1 we now have the following files, let’s take a look:

server1.crt <--- server1 cert (never share) 
server1.csr <--- certificate signing request - public
server1.key <--- your private key (never share)

7. Make a PEM out of the server1 certs:

cat server1.key server1.crt > server1.pem

The server1.pem goes to the server (In Hiawatha this means TLScertFile = /root/server1.pem)

8. Install the Squirrel5 repository and install Hiawatha:

yum -y install
yum -y install hiawatha

9. Configure Hiawatha

This is the Hiawatha config (/etc/hiawatha/hiawatha.conf) we’re using in this example (we’ve stripped out anything not necessary on purpose) :

Binding {
        Port = 443
        # The next line uses the PEM file we created in step 7
        TLScertFile = /squirrel5-CA-root/server1.pem 

Hostname =
WebsiteRoot = /var/www/hiawatha
StartFile = index.html

VirtualHost {
        Hostname =
        WebsiteRoot = /var/www
        RequireTLS = yes
        AccessLogfile = /var/log/server1.log
        ErrorLogfile = /var/log/server1-error.log

So what is the above doing? The above tells Hiawatha that:

“The site (Hostname = needs to be accessed over TLS (RequireTLS = yes)”

Let’s also throw a sample HTML page so we can get some output:

echo "<html><title>the squirrels...are watching</title></html>" > /var/www/index.html

10. Restart Hiawatha to apply the changes:

/etc/init.d/hiawatha restart

11. Now test with curl:


I got this error:

curl: (60) Peer certificate cannot be authenticated with known CA certificates
More details here:

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.

This is because our server doesn’t have our new CA key in it’s standard location (/etc/pki/ca-trust/source/anchors/) – let’s point curl manually to the CA cert according to the instructions from that error message:

curl -I --cacert /squirrel5-CA-root/rootCA.pem


curl --cacert /squirrel5-CA-root/rootCA.pem
<html><title>the squirrels...are watching</title></html>

Awesome that works!

12. OK, but how do I make this permanent so I don’t have to tell curl every time?

Copy your PEM to /etc/pki/ca-trust/source/anchors/

cp /squirrel5-CA-root/rootCA.pem /etc/pki/ca-trust/source/anchors/

And update the system’s CAs:

update-ca-trust extract

I got the following message:

update-ca-trust: Warning: The dynamic CA configuration feature is in the disabled state

Enable the dynamic CA configuration (note: this command has no output) :

update-ca-trust force-enable

Try accessing the site again, but this time don’t specify the CA:

<html><title>the squirrels...are watching</title></html>

13. Very cool, but what about authentication?

Good point! We can edit Hiawatha’s configuration so that it demands that you provide the client’s certificate – here’s how:

  • Edit the Hiawatha configuration (/etc/hiawatha/hiawatha.conf) and edit the Binding section:
Binding {
        Port = 443
        # The next line uses the PEM file we created in step 7
        TLScertFile = /squirrel5-CA-root/server1.pem
        # Require a client certificate that has been signed by the following CA
        RequiredCA  = /squirrel5-CA-root/rootCA.pem
  • Restart Hiawatha:
/etc/init.d/hiawatha restart
  • Try connecting again as before:
curl -I


curl -I
curl: (35) NSS: client certificate not found (nickname not specified)
  • Try again, but this time offer the client certificate:
curl --cert /squirrel5-CA-root/server1.pem
<html><title>the squirrels...are watching</title></html>

There we go – authenticated to the server by providing the client certificate.


Leave a Reply

Your email address will not be published. Required fields are marked *