A few years ago I wrote up a description of how I’d set up my own home certificate authority on RHEL/CentOS 5. Time for [another] update.
[Note these instructions have been updated again, in February 2015: to include options that will result in a SHA-256 key fingerprint instead of the (much) less secure SHA-1 fingerprint].
The major change I’ve made is in using the full openssl command line rather than the CA script.
Red Hat now sets aside /etc/pki as the directory where certificates and keys should live. An /etc/pki/CA subdirectory is provided for those of us wanting to create our own private Certificate Authority. On FreeBSD I create an /etc/ssl/CA directory for all of this.
1. First edit /etc/pki/tls/openssl.cnf to set your own defaults.
Here are the lines I chose to change, and some dummied up values:
dir = /etc/pki/CA certificate = $dir/certs/MyHomeCA.crt private_key = $dir/private/MyHomeCA.key default_days = 3650 countryName_default = US stateOrProvinceName_default = North Carolina localityName_default = Raleigh 0.organizationName_default = My Home default_md = sha256
Remember that openssl.cnf provides some handy defaults for your CA environment. If you choose not to set it up, you’ll need to remember to add additional parameters to the examples below.
Notice that I set the default days so my certificates expire a long time off (10 years, in fact). If I were doing this for anything other than my own home use I’d make that period a lot shorter, no longer than 2 years.
Then create an index.txt and serial file under /etc/pki/CA. Use the touch command for this, “touch serial index.txt”. Finally, insert “00” into the serial file (echo “00” >serial).
2a. Create the root key:
openssl genrsa -aes256 -out private/MyHomeCA.key 4096
2b. Create the root certificate:
openssl req -new -x509 -config openssl.cnf -key private/MyHomeCA.key -sha256 -days 3650 -out certs/MyHomeCA.crt
Answer the questions when asked. For the Common Name (CN) don’t put in a host name but something descriptive like “my-ca”. I would provide it a password to encrypt the key. If you need a decrypted version of an RSA key (for example if you’re importing into pfSense), you can use the following command to decrypt it:
openssl rsa -in MyHomeCA.key -out MyHomeCAdecrypted.key
It’s usually a good idea to give the decrypted version a different name, but not one so obvious as above.
See Note below for the “old” way of creating the root key and certificate.
3. Publish the root certificate file on an internal web server to make it easier for clients to get to. In my case I just did a symlink to my web server’s DocumentRoot:
ln -s /etc/pki/CA/certs/MyHomeCA.crt /var/www/html/certs/MyHomeCA.crt
4. Import the new root certificate into all your software (certificate distribution is a subject for another day).
5. To create new server certificates for services like HTTPS:
a. Make the key and certificate request.
openssl req -nodes -new -sha256 -keyout private/www.mydomain.com.key -out www.mydomain.com.req
Answer the questions as asked (including providing the password protecting the CA’s key). When it comes time to provide the Common Name (CN), you can put in “*.mydomain.com” to create a wildcard certificate good for all your subdomains, but some 3rd party software expects one, so know your target requirements.
b. Sign the request with your own CA.
openssl ca -out www.mydomain.com.crt -in www.mydomain.com.req
If you set a password on your CA, you’ll be asked for it again. Confirm that you want to sign and add the certificate to your certificate database (if you’ve messed up somewhere along the way and are creating a new cert whose CN matches a previous cert, you can remove the line with the duplicate CN from index.txt).
c. Edit your service configuration files appropriately so that they point to the new CA certificate file (MyHomeCA.crt), server certificate (www.mydomain.com.crt) and key (www.mydomain.com.key).
So long as you’ve imported the root certificate into the client software (for example, Firefox), you should be able to connect up over SSL without being prompted to accept a certificate.
Back in the good old days root keys and certificates were created with the following one-liner:
openssl req -new -x509 -keyout private/MyHomeCA.key -out certs/MyHomeCA.crt -days 3650
That might still work if your openssl.cnf is properly configured and read in by the openssl utility, but I think the 2-step method described in items 2a and 2b is the better practice.