From HerzbubeWiki
Jump to: navigation, search

I wrote this page when I first became interested in providing HTTPS access to my Linux box. I first had to learn a lot of stuff about SSL/TLS, and about X.509 certificate management. This page therefore has some introductory material on these topics, but its main concern is to show how to either

  • Manage server certificates with CAcert as the Certificate Authority (simple), or
  • Set up your own Certificate Authory and issue your own certificates (more complicated)


Provides a good overview over SSL/TLS, and also gives some details how to create your own SSL certificates:

Another interesting article/FAQ that is OpenLDAP-centric:

And, of course, the helpful Wikipedia article:

A Debian article that describes how to become your own root CA and sign your own certificates (note that the article was written in 2005 and is probably outdated at least in some parts):

Basics on SSL/TLS

What is SSL/TLS? 
A protocol to encrypt communication over a computer network. The protocol runs on top of the TCP and UDP protocols, but below any application protocols such as HTTP or FTP. In other words, it runs between the transport and the application network layers.
What is the difference between SSL and TLS? 
TLS is the successor to SSL. The SSL 3.0 specification was the last version of SSL to be published in 1996 by Netscape. The first version of TLS was TLS 1.0, it was published in 1999 in RFC 2246. The latest version of TLS as of writing this document is TLS 1.1, published in 2006 in RFC4346.
Probably most popular is the OpenSSL library, which is basically free but has a license that is not compatible with the GPL. An alternative was therefore created by the GNU project in the form of the GnuTLS, which uses the LGPL.

Basics on how communication encryption works

SSL/TLS is based on X.509 digital certificates, which in turn relies on the concept of public key cryptography. As users, we don't need to understand the mathematics that is underlying public key cryptography, so we can simply treat it as some kind of black magic that "just works". What we do need to know, though, are the working principles of public/private keys and X.509.

We begin at the beginning: Network communication occurs between 2 hosts. One of these hosts is the client, the other host is the server. The server has a pair of keys: The first of these is a public key which can be shared with the outside world, the second one is a private key that must remain secret to the server. When the client contacts the server, the server hands out its public key in the form of a digital certificate. A digital certificate is like a package that contains not only the public key, but also additional information that the client uses to make sure that the server really is whom it claims to be (more on that later). Assuming that the client accepts the certificate, it can now start to use the public key that was part of the certificate to encrypt the communication that it sends to the server. The server, being in the possession of the private key, is of course capable of decrypting the communication it receives from the client.

Before the client sends its first encrypted communication, it generates its own public/private key pair. It then encrypts the public key and sends it to the server. This enables the server to encrypt the communication it sends back to the client. The client, being in possession of the appropriate private key, is capable of decrypting the communication it receives from the server.

This is how a basic 2-way encrypted communication channel is established between a client and a server. Once the channel exists, client and server can use it to exchange information that further improves the security of the channel. Details on how this is done is beyond the scope of this wiki, though.

Basics on certificates

Having an encrypted communication channel is all good and fine, but there are more things to consider, chief among them how the client knows that the server it is communicating with is really the one that it thinks it is. When a client starts to communicate with, what happens behind the scenes is that the DNS system resolves to some IP address, then the client establishes a TCP connection with that IP address. So how does the client know that the server at the IP address really is Enter certificates...

How does the client know whom it is talking to, i.e. the server's identity? 
The server's identity is part of the certificate that it sends to the client. For instance, a certificate may claim that the server's identity is
How does the client know that the server's identity is genuine? 
The certificate that contains the server's identity must be digitally signed by a third party, a so-called Certificate Authority (CA). By issuing a signature, the CA vouches that the server's identity is genuine. An example for a commercial CA is VeriSign, an example for a community CA is A short discourse on digital signatures:
  • Digital signatures also work with the black magic of public key cryptography
  • The CA has a public/private key pair
  • The CA creates the signature using its private key
  • The CA hands out the public key - in the form of a digital certificate - that others can then use to verify that the signature is genuine
It is the server's responsibility to hand out to the client the CA certificate together with its own signed server certificate. Using the public key that is part of the CA certificate, the client is now capable of verifying that the server certificate's digital signature is genuine.
How does the client know that the CA certificate is genuine? 
Well, therein lies the rub: The client can't really know. Although it is possible to insert many levels of indirection, and to construct long chains of certificate signing, at some point the chain must come to an end. At the end of the chain is a so-called root CA - a certificate authority that nobody else is vouching for. The certificate of a root CA is self-signed. When the client encounters a self-signed CA certificate it can either decide to accept that certificate (and implicitly the entire certificate chain) as genuine, or it can decide to not accept the certificate. An SSL/TLS client bases its decision on whether it finds the self-signed CA certificate in a so-called trust store. The trust store is a list of CA certificates that are automatically trusted to be genuine. Which trust store a client consults, and how that trust store is managed, is an entirely different subject.

To sum this up, here's an overview of the certificates that are involved:

  • The client needs the server certificate so that it can encrypt messages it sends to the server. The client gets the server certificate from the server.
  • If the server certificate is signed, the client needs the CA certificate so that it can verify the signature. If there is a chain of signatures, the client needs the entire certificate chain. The client gets the certificate chain from the server.
  • If the server certificate is signed, the client needs a trust store of CA certificates that it ultimately trusts. The trust store is managed locally on the client side.

Generic procedure for creating and signing a certificate

  • The private RSA key is generated by the operator of the server
  • To let the CA sign the certificate, the server operator must contact the CA
    • First the operator creates a Certificate Signing Request (CSR)
      • The CSR contains various information about the applicant (in our case a server). The most important information for a server certificate is the attribute "common name" (sometimes also called "distinguished name"). This must be set to the FQDN under which the server is going to operate. If the FQDN contains a wildcard character (e.g. "*") the resulting certificate is called a "wildcard certificate".
      • The CSR is signed with the private key of the server operator
      • The CSR is accompanied with the public key of the server operator so that the CA can verify the signature when it receives the CSR
    • The operator sends his or her CSR to the CA
  • In response to the CSR, the CA generates the signed certificate
    • The CA first verifies the CSR signature against the server operator's public key which must accompany the CSR
    • The CA then generates the certificate using the information that the CSR contains about the applicant. The CA may decide not to use all information in the CSR. For instance, CAcert does not issue personalized server certificates, so any personal information in the CSR is simply ignored and will not be part of the certificate.
    • Finally, the CA signs the certificate with its private key
  • The server operator receives the signed certificate from the CA and may now use it
  • The server operator must make sure that the server hands out the signed certificate together with the CA certificate(s) that the client requires to verify the signature

The Certificate Authority (CA)

Let's Encrypt


From the "Getting Started" page:
In order to get a certificate for your website's domain from Let's Encrypt, you have to demonstrate control over the domain. With Let's Encrypt, you do this using software that uses the ACME protocol, which typically runs on your web host. [...[ We recommend that most people with shell access use the Certbot ACME client. [...] If Certbot does not meet your needs, or you’d like to try something else, there are many more ACME clients to choose from. Once you’ve chosen ACME client software, see the documentation for that client to proceed.

I have been successfully using Certbot, so that's what I am going to write about in the sections below.

Furthermore, because I want to have wildcard certificates, the following is also important (quote from the FAQ):
[...] Wildcard issuance must be done via ACMEv2 using the DNS-01 challenge.
What is a "DNS-01" challenge? Without going into details, the challenge requires you to add a custom TXT record to the domain's DNS configuration so that Let's Encrypt can verify that you are in control of the domain.


Preparing to use Certbot

Certbot is available as a Debian package. For Debian jessie, the recommendation is to install Certbot like this:

apt-get install python-certbot-apache -t stretch-backports

Unfortunately this Certbot package does not support issuing wildcard certificates. The workaround is to run Certbot in Docker. As a prerequisite therefore the first thing to do is to install the package:

apt-get install

I want wildcard certificates, so I can't use the plain Docker image certbot/certbot because that has no support for automating DNS-01 challenges. Certbot has a plugin concept, and some plugins that handle DNS-01 challenges (called "DNS authenticator plugins") exist for various popular DNS providers. Fortunately a Certbot plugin exists for my DNS provider, which is Cloudflare. The plugin name is cerbot-dns-cloudflare, and the corresponding Docker image which contains both Certbot and the plugin and that we are going to use is


Before we can proceed with requesting certificates, we first have to set up a bit of infrastructure on the local system. Later on when we run the Docker image we will instruct it to use that infrastructure. Step 1 is to create some folders:

mkdir /etc/letsencrypt
mkdir /var/lib/letsencrypt

Step 2 is to create the Certbot main configuration file /etc/letsencrypt/cli.ini that will be used by Certbot when it runs within the Docker image. The file content looks like this:

root@pelargir:~# cat /etc/letsencrypt/cli.ini
# Let's Encrypt site-wide configuration
dns-cloudflare-credentials = /etc/letsencrypt/
# Use the ACME v2 staging URI for testing things
#server =
# Production ACME v2 API endpoint
server =

Note the reference to /etc/letsencrypt/ This is the configuration file that will be used by Certbot's cerbot-dns-cloudflare plugin. It contains the Cloudflare API key which authorizes the Certbot plugin to automatically make DNS changes. This makes the configuration file very sensitive, and you need to make absolutely sure that the file is protected against unauthorized access. Note that we could protect against abuse with 2-factor authentication, but this would become a problem later on when we automate certificate renewal - you don't want to wake up in the middle of the night to confirm Certbot's renewal attempt. So this is how the config file looks like:

root@pelargir:~# ls -l /etc/letsencrypt/ 
-r-------- 1 root root 140 Jun  7 22:28 /etc/letsencrypt/

root@pelargir:~# cat /etc/letsencrypt/ 
# CloudFlare API key information
dns_cloudflare_api_key = 1234567890abcdef1234567890abcdef12345
dns_cloudflare_email =

Obtaining certificates

At the time of writing I had four domains for which I wanted a wildcard certificate, so these were the four commands that I issued:

docker run -it --rm --name certbot -v "/etc/letsencrypt:/etc/letsencrypt" -v "/var/lib/letsencrypt:/var/lib/letsencrypt" certbot/dns-cloudflare certonly -d -d *
docker run -it --rm --name certbot -v "/etc/letsencrypt:/etc/letsencrypt" -v "/var/lib/letsencrypt:/var/lib/letsencrypt" certbot/dns-cloudflare certonly -d -d *
docker run -it --rm --name certbot -v "/etc/letsencrypt:/etc/letsencrypt" -v "/var/lib/letsencrypt:/var/lib/letsencrypt" certbot/dns-cloudflare certonly -d -d *
docker run -it --rm --name certbot -v "/etc/letsencrypt:/etc/letsencrypt" -v "/var/lib/letsencrypt:/var/lib/letsencrypt" certbot/dns-cloudflare certonly -d -d *


  • The docker image to run is named "certbot/dns-cloudflare"
  • The --rm option causes the docker image to be removed after it has run. Note that --rm is a boolean option which normally wants either "true" or "false" as an argument. The general practice for Docker's command line is that not specifying a boolean option's argument is the same as specifying "true" - so here we are effectively saying --rm=true.
  • The -v option maps a folder from the host into the docker image (aka "mounting a volume" in Docker lingo). The two paths are specified with a colon (":") separator. Multiple -v options can be specified.
  • The -it option is actually two options:
    • The -i option is a boolean option that makes sure that the Docker process runs interactively (it opens STDIN)
    • The -t option is a boolean option that makes sure that Docker allocates a pseudo TTY and attaches it to the container's STDIN
  • The --name option assigns a name to the Docker container. Not important in this scenario
  • "certonly" is the command that is passed to the Docker image's entry point (set in the Dockerfile)
  • The -d option is an argument passed to Certbot. Multiple -d options create a single certificate that contains multiple subjects. The first -d is used for the main subject. The "Certificate Subject Alt Name" (Firefox term) or "X509v3 Subject Alternative Name" (OpenSSL term) lists all subjects, including the main subject. Certbot stores the certificate material in a folder named after the main subject (i.e. the first -d).

When you run one of the Docker commands you will be prompted as follows. Obviously you want to select option 1.

1: Obtain certificates using a DNS TXT record (if you are using Cloudflare for DNS). (dns-cloudflare)
2: Spin up a temporary webserver (standalone)
3: Place files in webroot directory (webroot)

We're almost ready to go now. A number of manual steps still have to be performed, though, before we can use the certificates that we just obtained.

Certbot files and folders

Certbot automatically creates a Let's Encrypt account when the first certificate is obtained. Certbot manages this automatically, so the details are not interesting here.

root@pelargir:~# l /etc/letsencrypt/accounts/
total 12
drwx------ 3 root root 4096 Jun  7 22:14 .
drwxr-xr-x 9 root root 4096 Jun  8 01:18 ..
drwx------ 3 root root 4096 Jun  7 22:14

Certbot creates and stores private keys here. These files are duplicates of the files stored in the archive folder, which is discussed further down.

root@pelargir:~# l /etc/letsencrypt/csr/
total 52
drwx------ 2 root root 4096 Jun  8 01:18 .
drwxr-xr-x 9 root root 4096 Jun  8 01:18 ..
-rw------- 1 root root 1704 Jun  7 22:14 0000_key-certbot.pem
-rw------- 1 root root 1704 Jun  7 22:17 0001_key-certbot.pem
-rw------- 1 root root 1708 Jun  7 22:23 0002_key-certbot.pem

Certbot creates and stores CSRs here:

root@pelargir:~# l /etc/letsencrypt/csr/
total 52
drwxr-xr-x 2 root root 4096 Jun  8 01:18 .
drwxr-xr-x 9 root root 4096 Jun  8 01:18 ..
-rw-r--r-- 1 root root  924 Jun  7 22:14 0000_csr-certbot.pem
-rw-r--r-- 1 root root  924 Jun  7 22:17 0001_csr-certbot.pem
-rw-r--r-- 1 root root  924 Jun  7 22:23 0002_csr-certbot.pem

As mentioned in the previous section, Certbot stores certificate material under the main subject's name, i.e. the first -d option specified on the Docker command line. Note the special permissions of the /etc/letsencrypt/live folder - these are non-standard and will be explained in the next section.

root@pelargir:~# l /etc/letsencrypt/live
total 28
drwx--x--- 7 root ssl-cert 4096 Jun  8 01:18 .
drwxr-xr-x 9 root root     4096 Jun  8 01:18 ..
drwxr-xr-x 2 root root     4096 Jun  8 00:10
drwxr-xr-x 2 root root     4096 Jun  8 01:18
drwxr-xr-x 2 root root     4096 Jun  8 01:18
drwxr-xr-x 2 root root     4096 Jun  8 01:10
drwxr-xr-x 2 root root     4096 Jun  8 01:17
root@pelargir:~# l /etc/letsencrypt/live/
total 12
drwxr-xr-x 2 root root     4096 Jun  8 01:10 .
drwx--x--- 7 root ssl-cert 4096 Jun  8 01:18 ..
lrwxrwxrwx 1 root root       35 Jun  8 01:10 cert.pem -> ../../archive/
lrwxrwxrwx 1 root root       36 Jun  8 01:10 chain.pem -> ../../archive/
lrwxrwxrwx 1 root root       40 Jun  8 01:10 fullchain.pem -> ../../archive/
lrwxrwxrwx 1 root root       38 Jun  8 01:10 privkey.pem -> ../../archive/
-rw-r--r-- 1 root root      682 Jun  7 22:32 README

As can be seen, the live folder consists of symlinks that together form the currently valid set of certificate material and that point back to an archive folder. Note the special permissions of the /etc/letsencrypt/archive folder and the special file courier.cert-and-key.unsecure - these are non-standard and will be explained in the next section.

root@pelargir:~# l /etc/letsencrypt/archive
total 32
drwx--x--- 8 root ssl-cert 4096 Jun  8 01:18 .
drwxr-xr-x 9 root root     4096 Jun  8 01:18 ..
drwxr-xr-x 2 root root     4096 Jun  8 00:10
drwxr-xr-x 2 root root     4096 Jun  8 01:18
drwxr-xr-x 2 root root     4096 Jun  8 01:18
drwxr-xr-x 2 root root     4096 Jun  8 01:10
drwxr-xr-x 2 root root     4096 Jun  8 01:08
drwxr-xr-x 2 root root     4096 Jun  8 01:17
root@pelargir:~# l /etc/letsencrypt/archive/
total 48
drwxr-xr-x 2 root root     4096 Jun  8 01:10 .
drwx--x--- 8 root ssl-cert 4096 Jun  8 01:18 ..
-rw-r--r-- 1 root root     2147 Jun  7 22:32 cert1.pem
-rw-r--r-- 1 root root     2163 Jun  8 01:10 cert2.pem
-rw-r--r-- 1 root root     1647 Jun  7 22:32 chain1.pem
-rw-r--r-- 1 root root     1647 Jun  8 01:10 chain2.pem
-rw-r--r-- 1 root root     5514 Jun  8 01:13 courier.cert-and-key.unsecure
-rw-r--r-- 1 root root     3794 Jun  7 22:32 fullchain1.pem
-rw-r--r-- 1 root root     3810 Jun  8 01:10 fullchain2.pem
-rw-r--r-- 1 root root     1708 Jun  7 22:32 privkey1.pem
-rw-r--r-- 1 root root     1704 Jun  8 01:10 privkey2.pem

Using Let's Encrypt certificates

The Let's Encrypt certificates will be used by the following services:

  • Courier IMAP: See the Courier wiki page for details. Most important is that Courier needs the certificate chain and the private key to be present in a single file. This is why we must manually create courier.cert-and-key.unsecure.
  • Exim MTA: See the Exim wiki page for details. Most important is that Exim needs special permissions on the /etc/letsencrypt/live and /etc/letsencrypt/archivey folders (group ssl-cert and permissions 710).
  • Apache: See the Apache wiki page for details.

Renewing certificates


From the output of the interactive use of the Docker image to obtain the initial certificates: "[...]To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew" [...]"

For Courier we need to stitch together the private key + cert chain.

Get root certificates

The public root certificates of can be obtained from this page (use the PEM variants):

At the time of writing there are 2 root certificates available:

  • a class 1 root certificate
  • a class 3 root certificate; this one is signed by the class 1 root certificate

Debian used to distribute the certificates in the Debian package ca-certificates. Unfortunately they stopped distributing the certificates in March 2014, so now we must install them manually. Following the conventions of the ca-certificates package, we install the certificate files in /usr/local/share/ca-certificates and create symlinks to those files in /etc/ssl/certs

root@pelargir:~# ls -l /usr/local/share/ca-certificates
total 8
-rw-r--r-- 1 root staff 2610 Oct 31 18:35 cacert.org_class3.crt
-rw-r--r-- 1 root staff 2569 Oct 31 18:35 cacert.org_root.crt

root@pelargir:~# ls -l /etc/ssl/certs | grep
lrwxrwxrwx 1 root root     54 Oct 31 18:43 cacert.org_class3.pem -> /usr/local/share/ca-certificates/cacert.org_class3.crt
lrwxrwxrwx 1 root root     52 Oct 31 18:43 cacert.org_root.pem -> /usr/local/share/ca-certificates/cacert.org_root.crt

Certificate chain file

Create a so-called certificate chain file in the following way:

cd /etc/ssl/certs
cat class3.crt >>
cat root.crt >>

The Apache web server is one of the applications that requires this chain file (it is specified by the directive SSLCertificateChainFile): When a client requests a server certificate such as for (which is signed by the class 3 root certificate), the server not only hands out the server certificate, but also provides the root certificates in the chain file. If the client trusts one of the root certificates, it will thereby automatically trust the server certificate, too.

Note: The certificates in the chain file should appear in the order of the certificate chain order, i.e. the root certificate that was used to sign the server certificate should appear first. I have not tested what happens if this is not the case, but it may affect browsers on the client side.

Manually add root certificates to browser

As per Wikipedia:

  • Class 1 root certificate is for email
  • Class 3 root certificate is for server certificates and software signing

If the browser supports it (e.g. Firefox does), also add the CRLs (certificate revocation list) for both root certificates.

Manually add root certificates to system (Mac OS X)

The following procedure works for me on Mac OS X 10.5.4:

  • Download the class 1 and class 3 certificates to the desktop (use the files in the DER format)
  • Import the class 1 certificate into the system keychain
    • Double-click on root.crt; this will open "Keychain" ("Schlüsselbundverwaltung" in German)
    • Select the keychain "System" (refers to /Library/Keychains/System.keychain)
    • Authenticate by specifying your administrator user's name and password
    • Confirm that you want to trust the certificate
  • Repeat the procedure by double-clicking on class3.crt (the class 3 certificate)
    • The certificate is automatically trusted because the root cert was already imported

Creating your own Certificate Authority (CA)

In order to act as your own CA, two things are needed

  • a private key
  • a certificate

In theory, the certificate can be obtained in 2 ways:

  • either create a self-signed public certificate
  • or create a CSR and convince a third party to issue the certificate for you

In practice, you will only use a self-signed certificate, because no other CA will issue a certificate to you that is capable of doing CA things. The reason is obvious: The other CA would lose control over the certificate issuing process, which is exactly what must never happen to a CA.

Private key

The following command creates a new private key with the following attributes:

  • the key is an RSA key
  • the key is protected by a passphrase that you must specify; the encryption algorithm/cipher used is Triple-DES
  • the key is formatted for PEM
openssl genrsa -des3 -out 1024

Example key file content:

osgiliath:~/ssltest# cat 
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,D238054F2ED5C62B


Self-signed certificate

The following command creates a new self-signed certificate with the following attributes:

  • the certificate has the X.509 structure
  • the certificate is signed with the CA's private RSA key
  • the certificate is formatted for PEM
  • the certificate is valid 30 years (= 10'950 days)
  • the certificate is capable of issuing other certificates (i.e. it is a CA certificate)
openssl req -new -x509 -days 10950 -key -out

Note: You must specify the passphrase in order to access the private RSA key.

OpenSSL will also ask for some information that will be incorporated into the certificate. The information is also called a "distinguished name" (DN) and consists of multiple fields or attributes. Attributes that you want to leave blank must be entered with a value "." It is advisable to enter at least the "common name" attribute:

Example DN:

  • Country Name (2 letter code) = CH
  • State or Province Name (full name) = .
  • Locality Name (eg, city) = .
  • Organization Name (eg, company) = Certificate Authority
  • Organizational Unit Name (eg, section) = .
  • Common Name (eg, YOUR name) =
  • Email Address =

Example certificate file content:

osgiliath:~/ssltest# cat 


The private key and the certificate (either self-signed or signed by a third party) should be stored in a permanent location. For instance:

Store the private key in:


Store the certificate in


To follow the guidelines of the ca-certificates package (see section below), we also need to create a hash symlink:

cd /etc/ssl/certs
ln -s "$(openssl x509 -subject_hash -in | head -1).0"

Last but not least, for those applications that are not able to follow a certificate chain (e.g. Apache, OpenLDAP), a single file with such a chain should be created:

cd /etc/ssl/certs
cat >>
cat class3.crt >>
cat root.crt >>

The server

Create a server key

The following command creates a new private key. It has the same attributes as the key that was created for the CA (see further up).

openssl genrsa -des3 -out 1024

Create a Certificate Signing Request (CSR)

The following command creates a CSR with the following attributes:

  • the CSR is formatted for PEM
openssl req -new -key -out

Example DN:

  • Country Name (2 letter code) = CH
  • State or Province Name (full name) = .
  • Locality Name (eg, city) = .
  • Organization Name (eg, company) = .
  • Organizational Unit Name (eg, section) = .
  • Common Name (eg, YOUR name) =
  • Email Address =
  • Challenge password: .
  • Optional company name: .

Note 1: It is important to set the "common name" attribute = the FQDN (fully qualified domain name) under which the server will operate, otherwise the information in the certificate will not match the information that the server announces to its clients. If a client is picky about this, the client may even refuse to cooperate with the server!!!

Note 2: Specifying the common name * will create a wildcard certificate that is valid for all sub-domains of


Store the private key in:


Store the CSR in:


Note: You may wish to store an un-encrypted version of the private key in /etc/ssl/private so that a server process can read the key without user interaction (i.e. the user entering the passphrase) during a system reboot. See the OpenSSL page for an example of how to do this.

The certificate

Sign the CSR through

The form to sign CSRs can be found here

Paste the CSR into the form, then sign it (by the class 3 root certificate, which is selected by default in the Web form) and thereby generate the certificate. The certificate can be copied and pasted into a certificate file. That file should be stored in


Sign the CSR through your own CA

Note: I recently discovered /usr/lib/ssl/misc/ which is provided by the openssl Debian package. Maybe it would be worth to have a look at that.

The first CSR

If this is the first CSR to be signed, I recommend creating a working directory that can be used to sign other CSRs in the future:

mkdir /usr/local/ssl
cd /usr/local/ssl
cp /usr/share/doc/libapache-mod-ssl/examples/ .
ln -s /etc/ssl/certs/
ln -s /etc/ssl/private/

Make the following modifications to the script

  • set CA_PREFIX to use
  • set default_days to a value that you find suitable; the attribute determines how long the signed certificate remains valid

Sign the CSR

The following command uses the script discussed in the above chapter to sign the CSR:

cd /usr/local/ssl

Store the file that contains the signed certificate in