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)
- 1 References
- 2 Basics on SSL/TLS
- 3 Basics on how communication encryption works
- 4 Basics on certificates
- 5 Generic procedure for creating and signing a certificate
- 6 The Certificate Authority (CA)
- 6.1 Let's Encrypt
- 6.2 CAcert.org
- 6.3 Creating your own Certificate Authority (CA)
- 7 The server
- 8 The certificate
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
www.herzbube.ch, what happens behind the scenes is that the DNS system resolves
www.herzbube.ch 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
www.herzbube.ch? 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 cacert.org. 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. "*.herzbube.ch") 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
- First the operator creates a Certificate Signing Request (CSR)
- 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)
IntroductionFrom 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.
- Let's Encrypt website
- Let's Encrypt information about wildcard certificates
- List of ACME clients. ACME is the communication protocol employed by Let's Encrypt to automatically issue certificates.
- Certbot website
- Certbot User Guide
- Running Certbot in Docker
- certbot-dns-cloudflare reference. This is the Certbot plugin that automates DNS-01 challenges.
- certbot-dns-cloudflare HOWTO from howtoforge.com
- certbot-dns-cloudflare HOWTO from eigenmagic.com
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
apt-get install docker.io
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/herzbube.ch.ini # Use the ACME v2 staging URI for testing things #server = https://acme-staging-v02.api.letsencrypt.org/directory # Production ACME v2 API endpoint server = https://acme-v02.api.letsencrypt.org/directory
Note the reference to
/etc/letsencrypt/herzbube.ch.ini: 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/herzbube.ch.ini -r-------- 1 root root 140 Jun 7 22:28 /etc/letsencrypt/herzbube.ch.ini root@pelargir:~# cat /etc/letsencrypt/herzbube.ch.ini # CloudFlare API key information dns_cloudflare_api_key = 1234567890abcdef1234567890abcdef12345 dns_cloudflare_email = firstname.lastname@example.org
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 herzbube.ch -d *.herzbube.ch docker run -it --rm --name certbot -v "/etc/letsencrypt:/etc/letsencrypt" -v "/var/lib/letsencrypt:/var/lib/letsencrypt" certbot/dns-cloudflare certonly -d moser-naef.ch -d *.moser-naef.ch docker run -it --rm --name certbot -v "/etc/letsencrypt:/etc/letsencrypt" -v "/var/lib/letsencrypt:/var/lib/letsencrypt" certbot/dns-cloudflare certonly -d francescamoser.ch -d *.francescamoser.ch docker run -it --rm --name certbot -v "/etc/letsencrypt:/etc/letsencrypt" -v "/var/lib/letsencrypt:/var/lib/letsencrypt" certbot/dns-cloudflare certonly -d grunzwanzling.ch -d *.grunzwanzling.ch
- The docker image to run is named "certbot/dns-cloudflare"
--rmoption causes the docker image to be removed after it has run. Note that
--rmis 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
-voption 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
-voptions can be specified.
-itoption is actually two options:
-ioption is a boolean option that makes sure that the Docker process runs interactively (it opens STDIN)
-toption is a boolean option that makes sure that Docker allocates a pseudo TTY and attaches it to the container's STDIN
--nameoption 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)
-doption is an argument passed to Certbot. Multiple
-doptions create a single certificate that contains multiple subjects. The first
-dis 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
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 acme-v02.api.letsencrypt.org
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 francescamoser.ch drwxr-xr-x 2 root root 4096 Jun 8 01:18 francescamoser.ch-0001 drwxr-xr-x 2 root root 4096 Jun 8 01:18 grunzwanzling.ch drwxr-xr-x 2 root root 4096 Jun 8 01:10 herzbube.ch drwxr-xr-x 2 root root 4096 Jun 8 01:17 moser-naef.ch root@pelargir:~# l /etc/letsencrypt/live/herzbube.ch/ 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/herzbube.ch/cert2.pem lrwxrwxrwx 1 root root 36 Jun 8 01:10 chain.pem -> ../../archive/herzbube.ch/chain2.pem lrwxrwxrwx 1 root root 40 Jun 8 01:10 fullchain.pem -> ../../archive/herzbube.ch/fullchain2.pem lrwxrwxrwx 1 root root 38 Jun 8 01:10 privkey.pem -> ../../archive/herzbube.ch/privkey2.pem -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 francescamoser.ch drwxr-xr-x 2 root root 4096 Jun 8 01:18 francescamoser.ch-0001 drwxr-xr-x 2 root root 4096 Jun 8 01:18 grunzwanzling.ch drwxr-xr-x 2 root root 4096 Jun 8 01:10 herzbube.ch drwxr-xr-x 2 root root 4096 Jun 8 01:08 herzbube.ch.org drwxr-xr-x 2 root root 4096 Jun 8 01:17 moser-naef.ch root@pelargir:~# l /etc/letsencrypt/archive/herzbube.ch 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
- Exim MTA: See the Exim wiki page for details. Most important is that Exim needs special permissions on the
ssl-certand permissions 710).
- Apache: See the Apache wiki page for details.
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 CAcert.org 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 CAcert.org 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
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 cacert.org 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 rm cacert.org.certchain cat class3.crt >>cacert.org.certchain cat root.crt >>cacert.org.certchain
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 www.herzbube.ch (which is signed by the class 3 CAcert.org 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 CAcert.org 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 Access.app" ("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.
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 ca.herzbube.ch.key 1024
Example key file content:
osgiliath:~/ssltest# cat ca.herzbube.ch.key -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,D238054F2ED5C62B hRy60/LS02UiWCtxJ5exSCX4nc1/bjSTfkR02PQhyrieAZjWK05YC5cYl17nobho 2evuG8QXCfEn4u6F/ckG9KcVD4LSpEPNOFijd/7lZjE7g07aP7Z11Bhqed03Orzh UTUwCPUXm9lxE+zypUmfY4F5r0MVSS3v5ULA4ckZMfkuCX4Ed0WNZjmqfyjLbwOr FA8TMDj7pb/HLiUt74TQyw58nENdNRG2NP/IAapMZvrj0+izxPD9LSmdFAAexAbY IcACNR4Ou5FypJE5d05PUVAPtBKYJQWdWW3lbOGovpQOdgLW7M13q/7doHYS0IHl sETcibGidhA6Nt4BI3XQ/LJgGV8v7ravmi7wj7ZvQ0l8INR5208E8rBQ6+QtoBsf A2nzZrd3L9k3GE05Tll8xp+vjkTkr38Kn31AGDz/W47bQfErYlbUutq4TvGIyFHl o6+MwqnsLHw88u9CneGprd6UNo49dLbcOrEX7CCnWSfRJR6oTb17yBbtCi2+yfBi 1Q+an7t3jTwDews3OAraSqCt/W5I8IHT4VLsDd+4T7TDXMWXYkqGv8rs+HlsMvGV YjOpwhFMk0ITJy8CkqP72TrsqRDBlhI7Rif2nT3kPOfJKwK6uc6F0S/Y0EuamhQu BqzPym4Nn35NmnWp7kI0C8ro9eu2i3shDUyW1GJdNvbzgiO3NVkvwq55LZA7YRQT tD0UIlEYmG8rD6BpQX3rwmU7utaE3jMuuW/G8BLHsRwo4F1IhbFQ0rmfXNKGBy+l NNx2zhpA44Hh+KR5RYcyl13nKsgmkevdt365XvGeQNrvrS8xHlGzLA== -----END RSA PRIVATE KEY-----
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 ca.herzbube.ch.key -out ca.herzbube.ch.crt
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:
- Country Name (2 letter code) = CH
- State or Province Name (full name) = .
- Locality Name (eg, city) = .
- Organization Name (eg, company) = herzbube.ch Certificate Authority
- Organizational Unit Name (eg, section) = .
- Common Name (eg, YOUR name) = ca.herzbube.ch
- Email Address = email@example.com
Example certificate file content:
osgiliath:~/ssltest# cat ca.herzbube.ch.crt -----BEGIN CERTIFICATE----- MIICsDCCAhmgAwIBAgIJAJS709dIawALMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMDcwMzI3MTkzMzIxWhcNMzcwMzE5MTkzMzIxWjBF MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB gQC8TmwotmWgM4mXoBqUOD/BYgwfPQ3Z31uMZnpAE1mvmYuE//pzy2dzTX4Y8wFH 2j6VzNFnqXy0Y5dULLc5kURswCIUSiMVUYWqSc5b+ybv1d0P5CSrypgk4tC0uYAz L43RAaAp+CJsBjKkesIKzQKfNODD5DoFf2z6SS6pwe52EwIDAQABo4GnMIGkMB0G A1UdDgQWBBSpWd567nU+3gOlS6b9wquTl3hBljB1BgNVHSMEbjBsgBSpWd567nU+ 3gOlS6b9wquTl3hBlqFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUt U3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAJS709dI awALMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAWy/SVVDw1YvorgU3 6yRtqjXBxSDEqTZRfGfGOxGiYhhJ6QyMHjy4b+MHoJRBYKaaq/ZmJbvob4bYskat X7vqrXO9/71JXSU10ZRRr7kczXNz0bZqeMtvtKi8ook0bdN/JwELp4pKHqWbI5od 7FuhwUSF17elipH/RuLLpalLfhk= -----END CERTIFICATE-----
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 ca.herzbube.ch.crt "$(openssl x509 -subject_hash -in ca.herzbube.ch.crt | 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 rm ca.herzbube.ch.certchain cat ca.herzbube.ch.crt >>ca.herzbube.ch.certchain cat class3.crt >>ca.herzbube.ch.certchain cat root.crt >>ca.herzbube.ch.certchain
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 foobar.herzbube.ch.key 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 foobar.herzbube.ch.key -out foobar.herzbube.ch.csr
- 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) = foobar.herzbube.ch
- Email Address = firstname.lastname@example.org
- 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 *.herzbube.ch will create a wildcard certificate that is valid for all sub-domains of herzbube.ch.
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.
Sign the CSR through CAcert.org
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/CA.sh 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/sign.sh . ln -s /etc/ssl/certs/ca.herzbube.ch.crt ln -s /etc/ssl/private/ca.herzbube.ch.key
Make the following modifications to the script sign.sh:
- set CA_PREFIX to use ca.herzbube.ch
- 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 sign.sh discussed in the above chapter to sign the CSR:
cd /usr/local/ssl ./sign.sh foobar.herzbube.ch.csr
Store the file that contains the signed certificate in