Every once in a while, the need arises for a certificate without the exorbitant price tag that comes with Thawte or Verisign. Of course, those outfits will give you a certificate that matches the CA certs built in to common browsers like Firefox and Safari. Or IE. But I don’t like IE. But for a personal email account over SSL or for an admin site for your company, why not create a self-signed certificate?
Using openssl one can do a multitude of cool things, including creating your own self-signed certificate.
Here’s an example of using a self-signed cert for web content.
For the exercises presented here, you’ll need access to the following:
- An Apache Webserver. It will match the configuration options I have presented here.
- A domain name. Just an example.com in your hosts file will work, or visit Network Solutions to purchase one.
- Access to the command line on the server that has your Apache install, with appropriate permissions to edit the configuration.
For my examples, I will be running Red Hat Enterprise Linux 4 (Update 6) and Red Hat’s Apache version for the implementation, and will be running Ubuntu 7.04 Desktop for some of the command examples. Typically, there shouldn’t be much difference in the commands run, but the implementation can vary from distro to distro. Ubuntu and Debian’s stock Apache implementations and configuration are very complex compared to Red Hat’s.
Once you have the requisites taken care of, then let’s get a little familiar with the openssl command.
Open up two terminals, and issue the following command:
$ openssl req -x509 -days 365 -newkey rsa:1024 -keyout hostkey.pem -nodes -out hostcert.pem
Press enter. You’ll see that this will spit out a LOT of information. To sum up, it basically says “Please tell me some information.” You’ll be prompted for the following information:
- Country Name (2 letter code)
- 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
Some key things to note are that the state should be fully typed out, ie, Texas, not TX. Also, the Common Name is the name of the URL that will be using the certificate, such as secure,ozymo.com.
This will create a hostcert.pem and hostkey.pem file containing the certificate and the ke, respectively:
$ ls -lah *.pem
-rw-r–r– 1 chuck chuck 1.4K 2008-02-17 15:09 hostcert.pem
-rw-r–r– 1 chuck chuck 891 2008-02-17 15:09 hostkey.pem
OK - so, we have our certificate and key now. Let’s give them a couple tests to make sure they work properly.
In the same terminal we just used, let’s issue these two commands to test continuity between the cert and the key:
$ openssl x509 -in hostcert.pem -noout -modulus
$ openssl rsa -in hostkey.pem -noout -modulus
These commands will spit out a modulus of the cert and key, and if they are the same, then the cert and the key match. If they differ, something has gone terribly wrong.
Another test we can set up includes creating a test server and test client, and this is where that other terminal you opened comes in. In the first terminal, which we have been using, issue the following command:
$ openssl s_server -accept 9000 -cert hostcert.pem -key hostkey.pem
This command will be followed by some output and the word “ACCEPT”. This means it is listening on port 9000. Now go to the other terminal, and run the following command as root or with sudo:
$ sudo netstat -ntpl | grep :9000
tcp 0 0 0.0.0.0:9000 0.0.0.0:* LISTEN 1668/openssl
As you can see, the server is listening. In the other terminal, run this command to make a connection. I have included some of the output, as I really wanted to illustrate only two key points in this example:
$ openssl s_client -connect localhost:9000 -CApath /etc/grid-security/certificates | grep handshake
depth=0 /C=US/ST=Texas/L=XXXXXX XXXX/O=The PiRS Network/OU=ozymo.com/CN=www.ozymo.com/emailAddress=chuckstearns@ozymo.com
verify error:num=18:self signed certificate
verify return:1
depth=0 /C=US/ST=Texas/L=XXXXXX XXXX/O=The PiRS Network/OU=ozymo.com/CN=www.ozymo.com/emailAddress=chuckstearns@ozymo.com
verify return:1
SSL handshake has read 1414 bytes and written 252 bytes
As you can see on line three of the ouput, there was a verification error because we have a self-signed certificate, but, on line 8, you can see that the SSL handshake was indeed successful.
So, let’s get this configured in an Apache vhost so that we can have secure, encrypted content. Sounds like fun, right?
First, you will need to upload the certificate. Do this in whichever manner suits you. I used scp.
Log into your server via SSH. Open the Apache configuration file in which your SSL vhosts reside. Add the following lines to enable the certificate we just created:
SSLEngine On
SSLCertificateFile /path/to/hostcert.pem
SSLCertificateKeyFile /path/to/kostkey.pem
I leave the rest of the configuration up to you, as it is your server.
Now, all that has to be done is to restart Apache, and visit the common name you used in the cert with the prefix https://
Remember that you will receive a cert error, because it it self-signed and not registered with any CA. Maybe we’ll cover creating a CA in a later entry.
/cs