SSL isn’t a security panacea, but customers have come to expect it. And it’s a good idea in many cases for internal use. Whether you’re looking at a temporary cert during development, or just want SSL without the cost on an internal site, self-signed certificates can do the job admirably.

Self-Signed SSL

October 22nd, 2007
Tags: , ,

A wise man once said, “There are three reasons to own a gun. To protect yourself and your family, to hunt dangerous and delicious animals, and to keep the King of England out of your face.”

Likewise, there are three reasons to use SSL. To protect your and your clients’ passwords, to secure e-commerce transactions, and to keep Karl Rove from outing you as a CIA operative.

Of course, going into some sort of retirement, I’d imagine Mr. Rove won’t be committing much more high treason, but I’m sure he’ll be kicking back, playing a little shuffleboard on the weekends, and probably reading your e-mail.

The second fall of Rome aside, SSL is always a good idea. If there’s one thing the Internet needs, it’s more security. Of course, SSL is pissing into the wind – almost all of our efforts are pissing into the wind. We’re never going to stop users from opening “WICKED COOL SCREENSAVER!!!!!!1111.EXE” – that must not deter our course, brothers.

Of course, SSL costs money, doesn’t it? Screw that, hey?

No, it doesn’t necessarily cost a dime. If you have users that can understand very simple sentences of three to four words, words that have no more than three syllables, you can deploy self-signed SSL certificates in places that don’t justify blowing $50-$300 on a genuine signed-by-some-money-grubbing-certificate-authority certificate.

Let us proceed with the rocking:

yum -y install mod_ssl

This will get you mod_ssl, which should in turn get you everything you need. And possibly then some, depending on what you’re setting up. For our purposes, I’m pretending you need an SSL-secured webmail installation. I’m also assuming you’re setting up SSL for a virtual host, simply because I have virtual hosts on my box, and damned if I’m setting up another VE for you people.

openssl genrsa -des3 -out domain.name.key 2048

(You'll be greeted with:)

Enter pass phrase for domain.name.key:

Why 2048? I like the idea of using 4096 myself, but some CAs seem to have issue with anything greater than 2048. For our purposes (self signing) it doesn’t matter, but this is the same step you’d use to prepare a key for use with a real certificate as well. domain.name should be your domain; for example, for foo.com, use foo.com.key. This standard will continue through the rest of the commands.

Enter a passphrase. Make it stupidly complex, something you won’t remember and can’t type without looking at it. But be sure to store it in a safe place. Your hard drive is not a safe place. Nor is a post it not attached to your monitor.

openssl req -new -key domain.name.key -out domaine.name.csr

(Time for interactivity:)

Enter pass phrase for domain.name.key:

Country Name (2 letter code) [GB]:
State or Province Name (full name) [Berkshire]:
Locality Name (eg, city) [Newbury]:
Organization Name (eg, company) [My Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

A challenge password []:
An optional company name []:

This is a certificate signing request, and it’s how you get a certificate – any certificate, be it self signed or not. The first prompt will be the pass phrase you created while generating domain.name.key.

As for the rest, since we’re self-signing, the values here don’t really matter all that much for the most part. If you’re running a respectable business and this is for some sort of internal mail server, you’ll likely want to use acceptable, ‘real’ values. If this is for personal use, I heartily endorse the idea of insisting you’re the Queen of England.

A word about e-mail address – I recommend you have a ‘hostmaster@your.domain’ set up. It’s damned useful for using for this sort of thing, as well as actual domain registration contact info. (Helps prevent you from being spammed just because you own a domain.) But really, you can use any e-mail address you wish. (Assuming it’s your e-mail address.)

I’ve never yet filled in a challenge password or an optional company name. Next.

cp domain.name.key domain.name.key.bak
openssl rsa -in domain.name.key.bak -out domain.name.key

Enter pass phrase for domain.name.key.bak:

chmod go-rwx domain.name.key
chown root:root domain.name.key

Again, this is the pass phrase from the first step. What are we doing here? We’re (*gasp*) removing the encryption from the key. Why? Because sooner or later your server is going to have a problem at three in the morning, and your hosting company, being the nice people they are, are going to try to fix it. We want them to be able to restart Apache, yes?

The problem with encrypted keys is, Apache won’t start without which you enter the passphrase. If your system goes down for any reason and comes back up, it’ll be stuck in boot, waiting for you to type in the passphrase. If something happens and Apache needs to be restarted, same deal. Bad thing, all around.

The last two commands, by the way, ensure that only the root user can read the key. Thus, if someone manages to read the key, you have bigger problems anyhow, because your system has been wtfpwned.

openssl x509 -req -days 999 -in domain.name.csr -signkey domain.name.key -out domain.name.crt

Congratulations, you now have a self-signed SSL certificate. Now it’s time for some Apache configuratin’:

cp domain.name.csr /etc/httpd/conf/ssl.csr
cp domain.name.crt /etc/httpd/conf/ssl.crt
cp domain.name.key /etc/httpd/conf/ssl.key

vi /etc/httpd/conf/ssl.conf

In this file, you want to find:

<VirtualHost _default_:443>

…And comment it out. Comment everything out that isn’t commented out, until you reach:

</VirtualHost>

…And comment that out, too. Then save and exit.

vi /etc/httpd/conf/httpd.conf

Time to set up your real virtual host entry. Here’s an example of one:

<VirtualHost IPADDRESS:443>
ServerName HOSTNAME
DocumentRoot /path/to/html
ErrorLog /path/to/error_log
CustomLog /path/to/access_log combined
SSLCertificateFile /etc/httpd/conf/ssl.crt/domain.name.crt
SSLCertificateKeyFile /etc/httpd/conf/ssl.key/domain.name.key
SSLEngine on
</VirtualHost>

IP address is naturally the IP address of your system, or at least the IP address the domain you’re using is pointing at. ServerName is the hostname, and should be what you listed for ‘Common Name’ on the certificate signing request. The rest, I leave to you. Anyhow, once done, restart Apache:

/etc/init.d/httpd restart

Open your web browser, go to your domain, using https instead of http. You should get a little window. The message varies with your browser, but should basically say, ‘Oh noes, I don’t recognize this Certificate Authority!11111111111′

If you want, examine the details, but unless you did something really wrong, it should be your certificate. FireFox, at least, will allow you to accept the certificate permanantly; which if you’re setting up an internal site or something for a company, might be a good idea to click. (Less confused users.)

No such option with IE – at least not IE6. Such is life, but you now have SSL, even if Microsoft doesn’t recognize you as a certificate authority.

It’s okay; after all, no one respects their authority, either.

So what’s next? You now have SSL on a domain. You can set up all sorts of crazy things, or you can do something useful and set up webmail or something. The sky is the limit, or some such.