Self-Signed SSL

by gary on Sun, 08/19/2007 - 15:25

Internet security is like urinating to windward. No matter what we do, we're never going to stop users from using a certain web browser, a certain mail client, a certain operating system, and opening every .exe or suspicious file that gets sent to them. That shouldn't stop our efforts, though. If there's one thing the Internet needs, it's more security.

SSL, is, well, SSL. It's that cool little lock icon at the bottom of your screen; it's the funky little yellow bar that tells you, "This site is secure! Woo!" And it's a good idea to make sure it's anywhere and everywhere you have passwords going to a web browser.

There is, however, a problem of cost. SSL certificates signed by a recognized authority cost money; in some cases, a great deal of money. Not only that, but there are disreputable "authorities" whose certificates are not widely recognized. They'll happily take your money despite doing no better job than a self-signed cert. But that's another rant entirely.

Everyone loves money, and so, I dare say that's the main reason SSL isn't more widely used. You either spend money, or you risk getting confused users. There are plenty of cases where you do not want confused users. E-commerce is one of them - even I'm not going to place an order on a site that has SSL-related warnings popping up, whether when examining the certificate it looks valid or not. If I, sysadmin that I am, will not place an order at such a site, what are the chances that the average user, having heard nothing but horror stories of credit card and identity theft over the past few years, will?

None. E-commerce, public-facing websites, etc. These things, you need to shell out cash for certificates for if you want SSL.

But there's yet a place for self-signed certificates, one often overlooked. Development servers, staging systems, company-owned e-mail servers (assuming you're using sane clients that can do away with the nag-box generated by a self-signed cert)...

These beg for the benefits of SSL, without the cost of buying a new SSL cert every year.

Of course, the question must be asked: Do we need, with the hundreds already out there, another walkthrough for setting up a self-signed SSL certificate? Judging by the number of customers I've dealt with who were musing about SSL over the past few years, yes, yes we do.

yum -y install mod_ssl

This will get you mod_ssl, which should in turn get you everything you need. Your mileage may vary on non-RedHat based distributions.

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

(You'll be greeted with:)
Enter pass phrase for domain.name.key:

Why 4096? I like big numbers. 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. I am, of course, assuming you're setting up SSL on a virtual host, here.

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 note 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, you'll likely want to use acceptable, 'real' values. If this is for personal, non-professional use, I heartily endorse the idea of insisting you're the Queen of England. You might amuse a user or two.

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. This is the sort of nightmare that can turn a five minute downtime into a three day nightmare, while people run about as if headless chickens, trying to get in contact with the dude who knows the passphrase - who is on vacation in Djbouti.

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, to put it mildly, 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. Gondor needs no blanket virtual host configuration. 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'

Congratulations. You now have a working self-signed SSL certificate, perfect for saving money on development environments, staging systems and/or when you have users who can grasp the fact that you're using a self-signed cert.

Tags: apachesecurityssl

gary's blog  
    Delicious  Digg  Reddit  Technorati  

Comments

Help

Gary,

Could you please contact me at rbh at 315caxton.com. I cannot access my server. Please delete this comment.

Rob

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.

More information about formatting options