Certification Authority
2012-12-07
Providing a secure channel to your server is essential. Many services uses the TLS protocol and you need a Certificate to use it. This article discusses different options and shows you how to set up your own CA and using it to generate certificates.
Introduction
To secure the communication of many services the TLS protocol is used. To enable it for our applications we need a certificate. We can get these certificates from a company that sell them, or get a free one from StartSSL, or get a free one from CA Cert, or make your own Certification Authority (CA). One can also just self-sign a certificate but that is not recommended, the CA certification has a purpose.
There are several advantages and drawbacks with each selection. Using a commercial vendor costs money. Symantec, the market leader takes $599/year at the time of this writing for a "Secure Site SSL Certificates", their simplest certificate. This certificate is just valid for one URL. You have to have a better reason to give out so much cash then to just safely read your email over IMAPS. The advantage is that your certificate is well known and accepted by all browsers.
A cheaper alternative is StartSSL that is accepted by most browsers and has a different pricing structure. A simple combination (example.com/www.example.com) is free, but has the requirement that you validate your domain once a month. The certificate is only valid one year and you will have then to update it again. They have a "StartSSL™ Verified" product that costs $59.90 per year. You have to provide personal information for this product, like copy of your passport etc. You are allowed unlimited two year certificates for a year (eg 350 days). StartSSL is located in Israel.
CA Cert is a Certificate Authority that provides free certificates. One big drawback is that the CA is not included in many browsers, due to the need for an expensive Webtrust audit. This means that if a user comes to your site they will be greeted with a big red warning in the browser that your site is not trusted. They can then add the root certificate to their browser, and then your site will be trusted. This step is not very easy for a non-technical user.
A self signed CA have the same problem with inclusion in web browsers as CA Cert but to that your users need to trust you personally, or at least your CA. There are situations where the control of a self signed CA is useful, for example in a Company where you then can provide your users the CA in a central manner. Still adding the CA to all different devices can be difficult.
Building a Certification Authority
First we must make a structure on our encrypted partition to hold all our future keys and certificates. We also need to set up the appropriate serial and crlnumbers. Easy steps with the following commands.
cd /mnt/crypt/ca/
,
mkdir example.org-CA
,
cd
example.org-CA
and
mkdir certs crl newcerts
private req key-certs keys user-p12
, Create some basic files,
touch index.txt
,
echo '01' >
serial
and
echo '01' > crlnumber
.
Now we are ready to start creating things for our CA, but first we need a configuration file. We will use the standard debian file, but we'll store it to the CA directory so that we can add any special commands to it. The openssl configuration file can sometimes be overridden by the command line but in other cases it is harder. Therefor it is better to have a file for you CA where your settings are stored. First copy the debian default file to the CA directory.
cp /etc/ssl/openssl.cnf
.
. We change the dir to point to the current
directory. dir = .
. Lets also
set countryName_default, stateOrProvinceName_default,
0.organizationName_default, organizationalUnitName_default and
emailAddress_default so that we don't have to enter a full
string every time. For emailAddress_default we can put for
example cert@example.org to create a contact point for
certificate questions.
Now, we can start to create the CA. Lets start to generate the main key. This key will control the CA and we must make sure that we do not loose it, and pick a difficult long pass phrase. We can let pwsafe generate a password for us. One can get pretty much impossible long and complex password from the pwsafe.
openssl genrsa -aes256 -out private/cakey.pem
4096
generates the key. To create the CA certificate we now do
openssl req -config openssl.cnf -new -x509
-extensions v3_ca -days 1095 -sha1 -key private/cakey.pem -out
cacert.pem
. From the soup of options we have picked
to create a key with AES256, and for the certificate we have
selected the SHA1 hash algorithm. The CA is valid for 3 years,
and that is a good start. Extension v3_ca points to a section in
your configuration file, where some basic CA settings are
set. For the common name we set simply
example.org ca
Creating server certificates
Now we when we have a CA we can create our first certificates. For what services do we need a certificate ? To begin with we create certificates for a webserver running several virtual hosts. (exemple.org, exemple.com and exemple.net). Then we also create a certificate for our mailserver and our ldap server, named mail.example.org and ldap.example.org.
To create a certificate for multiple hosts we need to add some
information to the openssl.cnf
. At the end
of the file we create a new section for a request called
req_www.example.org.
[ req_www.example.org ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @example_names
to that section we add another for our CA certification :
[ ca_www.example.org ] basicConstraints=CA:FALSE subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer subjectAltName = @example_names
Both these sections points to a third section we have to create. That section lists all names we want the server to be valid for :
[example_names] DNS.1 = example.org DNS.2 = www.example.org DNS.3 = example.net DNS.4 = www.example.net DNS.5 = example.com DNS.6 = www.example.com
Now we can start creating keys and requests that we later can sign with our CA to certificates.
First we generate the key
openssl genrsa -aes256 -out
keys/key-www.example.org.pem 2048
and now we just pick an password with pwsafe and store it at the same time. Since the password will be used to start the SSL server, it will be used every time so keep the pwsafe handy, and have a backup. Then we create a request so our CA can sign a certificate.
openssl req -config openssl.cnf -new -nodes -reqexts
req_www.example.org -out req/req-www.example.org.pem -key
keys/key-www.example.org.pem
Here the section we created in the configuration file is use with the command line switch -reqexts. The common name should be example.org matching the DNS.1 entry.
The mail server and the ldap server are simpler since the certificate are only for one common name. Do the same procedure with these and give the common names mail.example.org and ldap.example.org.
openssl genrsa -aes256 -out
keys/key-mail.example.org.pem 2048
and
openssl req -config openssl.cnf -new -nodes -out
req/req-mail.example.org.pem -key
keys/key-mail.example.org.pem
. The same for the LDAP server
openssl genrsa -aes256 -out
keys/key-ldap.example.org.pem 2048
openssl
req -config openssl.cnf -new -nodes -out
req/req-ldap.example.org.pem -key
keys/key-ldap.example.org.pem
.
Now we have a bunch of requests that we would like to sign, to create properly signed certificates. The www.example.org certificate needs the extension flag to add the additional names.
openssl ca -config openssl.cnf -extensions
ca_www.example.org -out certs/cert-www.example.org.pem -infiles
req/req-www.example.org.pem
creates the signed certificate. We have to enter the CA pass phrase and decide if we want to sign the request. Lets sign the www.example.org request. We sign the mail.example.org and ldap.example.org certificate as well.
openssl ca -config openssl.cnf
-out certs/cert-mail.example.org.pem -infiles
req/req-mail.example.org.pem
and
openssl ca
-config openssl.cnf -out certs/cert-ldap.example.org.pem
-infiles req/req-ldap.example.org.pem
.
The certificate can also be made slimmer by stripping it of the human readable text. Lets do that and create a copy with a stripped version.
openssl x509 -in
certs/cert-www.example.org.pem -out
certs/cert-www.example.org-s.pem
. The command is simple and can be used for all the generated certificates.
openssl x509 -in certs/cert-mail.example.org.pem -out
certs/cert-mail.example.org-s.pem
openssl
x509 -in certs/cert-ldap.example.org.pem -out
certs/cert-ldap.example.org-s.pem
Sometimes a separate key and cert file are needed and sometimes a combined file. That depends on the application. To combine the two files just
cat keys/key-www.example.org.pem
certs/cert-www.example.org-s.pem >
key-certs/key-cert-www.example.org.pem
The last step we do is to create a revocation list. This lists what certificates are valid and what have been invalidated.
openssl ca -config openssl.cnf -gencrl -crldays 31 -out
crl/ca-crl.pem
Revoking your certificates and replacing them
This section I had to write faster then I intended. The DSA-1571 made me look into this very quickly. I had some problem finding how self-signed certificate authorities are handled but this thread on openssl-user gave me some hints. I wish this information would have been published on the Key Rollover page, since it is not so common to change CA.
So, lets get those broken certificates out of the wild. We start by creating new CA that we can trust. First move the key and certificate out of the way.
mv cakey.pem
cakey.pem-dsa-1571
and
mv cacert.pem
cacert.pem-dsa-1571
. Then move the password inside the pwsafe so that we still have access to the password, but can create a new for the new certificate.
pwsafe -e
tree.se.cert.ca
. Changing the name
name: [ca] ca-dsa-1571
. If
your CA expired or was compromised because of some other reason
you can put old or whatever instead of dsa-1571.
Now we generate a new key and set a new password.
openssl genrsa -aes256 -out private/cakey.pem
4096
and
pwsafe -a
with the input
name: ca group [<none>]: tree.se.cert username: current password [return for random]: Generate random password? [y]
Then we generate the CA.
openssl req -config
openssl.cnf -new -x509 -extensions v3_ca -days 1095 -sha1 -key
private/cakey.pem -out cacert.pem
Now we need to retire the broken certificates. But first lets move the certificate out of the way, so that we do not accidentally delete them.
mv key-example.org.pem
key-example.org.pem-dsa-1571
. We move all the certs out of the way as well. We also need to rearrange the pwsafe, so we know which keys belong to which certificates.
So lets start revoking.
openssl ca -config openssl.cnf
-revoke certs/cert-ldap.example.org.pem-dsa-1571 -keyfile
private/cakey.pem-dsa-1571 -cert cacert.pem-dsa-1571
and it will tell you Revoking Certificate 03.
Data Base Updated
. Then do the same with all
certificates.
Now we start create new certificates like we did earlier, in the section above. Once that is done we need to publish them and create CRL file to be able to tell the world about the withdrawn certificates. To generate the CRL do
openssl ca
-config openssl.cnf -gencrl -crldays 31 -out
crl/ca-crl.pem
.
Renew server certificates
Once the certificates expires one can easily renew them with
a script like in
#!/bin/bash
date=`date +%d-%b-%Y`
_renew () {
echo " ----=== $1 ===----"
openssl genrsa -aes256 -out $date/keys/key-$1.pem 2048
if [[ $1 == www* ]]
then
openssl req -config openssl.cnf -new -nodes -reqexts req_$1 -out $date/req/req-$1.pem -key $date/keys/key-$1.pem
openssl ca -config openssl.cnf -extensions ca_$1 -out $date/certs/cert-$1.pem -infiles $date/req/req-$1.pem
else
openssl req -config openssl.cnf -new -nodes -out $date/req/req-$1.pem -key $date/keys/key-$1.pem
openssl ca -config openssl.cnf -out $date/certs/cert-$1.pem -infiles $date/req/req-$1.pem
fi
openssl x509 -in $date/certs/cert-$1.pem -out $date/certs/cert-$1-s.pem
cat $date/keys/key-$1.pem $date/certs/cert-$1-s.pem > $date/key-certs/key-cert-$1.pem
}
mkdir -p $date/keys $date/req $date/certs $date/key-certs
_renew www.example.com
_renew special.example.com
Please note that www.example.com is a special case, and needs an
appropriate section in the openssl.cnf file, as discussed above.
One still have to approve the suggested defaults, and write the
Common Name (CN) at the prompt. All passwords for the keys and
the CA has also to be provided. Still it is faster than writing
all the commands by hand.