Currently I’m digging myself into the world of administrating servers. I started with webservers but by now I’m administrating multiple servers that run services like DNS, HTTP, Mail, SVN, MySQL, PostgreSQL and a couple more. My last thing was DNS. I’ve read through the reference book from O’Reilly: DNS & Bind and set up two authoritative and one public DNS server.
Now that I’ve set up all this stuff I need to dig into the next thing. I wanted my fellow students and the professors at my university to use secure connections when they would log into their mail accounts, weblogs and wikis. Therefor I would have to deploy certificates. Since the administrators of my university were unable to create proper certificates I decided to create a CA on my own. So I started reading a bunch of tutorials about HTTPS and OpenSSL. None of these were really satisfying as they would only go for a quick fix. »Create a CA, create certificates, configure apache, don’t care about the details.« – That is what most of the tutorials were like. If I would go as far as creating my own CA for our faculty I wanted to make it as good as I possibly could. Therefor I started reading even more tutorials and howtos just to find out that almost everybody is doing it differently. There wasn’t the definitive guide I was hoping for. Then I got the Secure Networking with OpenSSL book from O’Reilly which had yet another approach. Even a friend of mine, who is earning tons of money deploying PKI for large corporations, couldn’t answer all my questions. In the end I came up with my own solution which is a mixture of the OpenSSL book and the expertise of my friend.
It goes like this:
First of all, if you really want to save you a lot of pain, create your own custom openssl.cnf. If it is setup properly you’ll save you a lot of typing and get a lot more consistency automatically. The book, in contrast to most tutorials, starts by creating a directory for all your certificates and keys.
> mkdir /usr/local/etc/ssl > cd /usr/local/etc/ssl > mkdir crl #for cert revocation lists > mkdir certs #this is where new certs go > mkdir private #this is where the key go > touch index.txt #file to keep track of your certs > echo 01 > serial #file to keep track of the serials
Thats gives you the basic structure. Of course you should set the proper permissions to prevent access from others. Your private CA key should be really private. Once obtained you can start all over again and worry about your security nightmares becoming true.
Now lets get to the openssl.cnf file. On FreeBSD edit vi /etc/ssl/openssl.cnf
.
The default openssl.cnf is very long and not that easy to understand when you look at it for the first time. I won’t explain everything to you, instead this is a guide for people who want to create their own CA and are willing to read through the book, the man pages or the tutorials which I will also post at the end.
The most important part to understand the openssl.cnf is probably the [ foo ] syntax. It works like this:
default_ca = CA_default
In this case you’re saying the default_ca
is defined beneath the secttion CA_default
.
The section itself is defined beneath [ CA_default ]
and it goes until the next [ section ]
definition
# To use this configuration file with the "-extfile" option of the # "openssl x509" utility, name here the section containing the # X.509v3 extensions to use: extensions = certificate_extensions #################################################################### [ ca ] default_ca = CA_default # The default ca section #################################################################### [ CA_default ] dir = /usr/local/etc/ssl # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. #unique_subject = no # Set to 'no' to allow creation of # several ctificates with same subject. new_certs_dir = $dir/certs # default place for new certs. certificate = $dir/cacert.crt # The CA certificate serial = $dir/serial # The current serial number crlnumber = $dir/crlnumber # the current crl number # must be commented out to leave a V1 CRL crl = $dir/crl.pem # The current CRL private_key = $dir/private/cacert.key# The private key RANDFILE = $dir/private/.rand # private random number file x509_extensions = certificate_extensions# The extentions to add to the cert default_days = 720 # how long to certify for default_crl_days= 10 # how long before next CRL default_md = sha1 # which md to use. preserve = no # keep passed DN ordering policy = policy_match # For the CA policy [ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = supplied commonName = supplied emailAddress = optional
This part defines the location auf the ssl directory and all the other files. It also defines the section for the x509 extensions. In my configuration they look like this:
[ certificate_extensions ] # These extensions are added when 'ca' signs a request. basicConstraints=CA:FALSE # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer # Copy subject details issuerAltName = issuer:copy keyUsage = digitalSignature,keyEncipherment extendedKeyUsage = serverAuth,clientAuth crlDistributionPoints = URI:http://yourdomain.com/crl nsCaPolicyUrl = URI:http://yourdomain.com/policy
This is actually the part where my friend helped me out. Most of the quick fix tutorials leave out the x509 extensions which are crucial for a serious CA and certificates as they give the the potential clients further information about the key usage, the policy and the revocation lists. It doesn’t provide more security but more seriousness and it is a lot better than a certificate which has no real information at all (e.g. Some Organization, Some City, Some Stat).
You can view the rest of my openssl.conf by clicking on this link. Take a look at the x509 extensions in particular as some of them are not in the default config file.
After you set up your openssl.cnf its time to get started creating your CA.
Issue the following command. This will create a CA key/cert pair. Also note that the CA certificate belongs into ssl/cacert.crt. You can change this in you openssl.cnf though.
Step 1:
openssl req -new -x509 -keyout private/cakey.pem -out cacert.pem
Enter all the details you want to have in your certificates. Thats it, you have now a self signed CA. Now continue by creating a new key and a certificate signing request by tying:
Step 2:
openssl req -newkey rsa:1024 -keyout testkey.key -keyform PEM -out testreq.csr
Note that the bitlength of 1024 is recommended for HTTPS as many clients / browsers do not support higher values. I don’t know if this is still valid. If you tried out or know by fact that all current browsers support higher values, let me know! Since this certificate is for a browser and you want it to work with older browsers too you specify 1024 bit. Now you can sign this certificate signing request with your CA certificate.
Step 3:
openssl ca -in testreq.csr
You will now be promted with the certificate request information and the question whether to sign it. After confirming the request a new serial is written to the ssl/serial file and the hash of the new cert will be appended to index.txt. Your new cert is created in ssl/certs/.
Now you can continue creating new certificates under your new CA by repeating step 2 and 3.
To complete this post I’m going to list all the webpages I consulted for help and that had indeed useful information (I’m skipping the quickfix ones):
- Overview of the OpenSSL configuration file
- x509 Extensions explained
- HTTPS and Apache Tutorial (you can skip the CA part)
So in the end this seems like a quick fix tutorial as well. It is indeed but I think this one works really well and provides you with a proper openssl.cnf as well as some useful links. Again – read the book and manpages as you will probably discover some more details about PKI in general. I hope this post was any help for you.
The HTTPS and Apache Tutorial Link is broken.
What do you think of using a Makefile to create various certs on FreeBSD? Such a thing should be in BASE in a nicely prepared /etc/ssl/ … copying this idea from the Linux distro Fedora which has /etc/pki/ and to create the various certs etc one needs for TLS/SSL enabled applications one does:
cd /etc/pki/tls/certs
make slapd.pem
etc… check out /etc/pki/tls/certs/Makefile on a Fedora install or look here:
http://cvs.fedora.redhat.com/viewvc/devel/openssl/Makefile.certificate?revision=1.4
I urge the usage of RSA 4096 in place of the weak 1024.
This link was very helpful for a newbie liek me to start on OPENSSL. Helped me a lot. Thanks.
Looks like the link to your full config file is broken.
Nevertheless, many thanks for your tutorial!
The link to your openssl.cnf is broken