Up until now I’ve only used SSL on my web server to encrypt my WordPress admin traffic. A self-signed certificate was fine for that since I wasn’t worried about confirming the identity of my server. But recently I’ve had a couple situations where I wanted integration that required a trusted certificate (one issued by a recognized certificate authority). I’ve been able to implement work arounds but they seemed to compromise security, if only by a little. So I decided to go out a get an “official” SSL certificate.
I’ve been considering it for awhile. I’d basically decided on DigiCert to provide the certificate long ago. They came to my attention, along with a lot of information about certificates in general, while listening to Steve Gibson’s Security Now! podcast. In 2011 he was shopping for a new certificates provider and talked about it over several episodes over a couple months. They aren’t a bargain basement shop, but they aren’t outrageous either.
What I Have Now – What I Want
I have a VPS server with Linode with one IP address and a self-signed certificate used by all sites on that IP address. I want to get to a configuration where one of those sites uses a trusted certificate and the others continue to use the self-signed certificate.
Implementation – Pulling the Parts Together
1. First step is to add an IP address to my server for the new certificate. There are certificate types that can secure multiple websites on one IP address, but I’m only buying the certificate for one site. So I need one IP address for the self-signed certificate and one for the trusted certificate. Linode requires a support ticket to justify the new IP address. There were some forum threads that said this was a difficult process. Maybe it’s because I only need 1 extra IP, but it was fast and simple. I just said I was adding a SSL certificate. I had the new IP address about an hour later (on a Sunday).
2. I followed these instructions to add my second IP address once it was assigned. The only difference from the instructions was I did list the gateway for the second IP address and I needed to reboot the server to recognize the new IP address. Cycling network services wasn’t enough and in fact displayed a message that it might not work.
3. Next I needed to get the SSL certificate. I removed domain privacy on the domain for which I was getting the certificate in order to streamline the proof of ownership. I did restore privacy once the certificate was issued. I followed DigiCert’s instructions on Apache. Those instructions include a tool to create the Certificate Signing Request (csr). When I used the tool it recognized I wasn’t their customer and offered a 30% discount along with an extra 60 days. So if your planning multiple purchases be sure to try the big one first, the offer hasn’t come up since I bought my certificate. The tool generated a command line I had to run on my server to create the csr. After running the command I copied the generated .csr file to my local computer, opened in in a plain text editor and pasted the contents into the DigiCert certificate order form. Since it was Sunday, and DigiCert says they don’t offer support on Sunday (except for emergencies), I didn’t expect a response. Instead I go one a short time later asking for supporting documentation to prove who I am and I sent that along. I had the certificate about 2 hours after submitting the order.
Implementation – Adding the SSL Certificate
1. At the time I generated the CSR (step 3 above) it also generated my private key which needs to be protected. I’ll keep the private keys in /etc/ssl/private which is the default location on my Debian 6 server. So I copy the file there and make sure it’s only accessible by root.
sudo mv /path/to/file/www_mydomainname_com.key /etc/ssl/private
sudo chown root:root /etc/ssl/private/www_mydomainname_com.key
sudo chmod 600 /etc/ssl/private/www_mydomainname_com.key
2. I’ll keep the actual certificates in /etc/ssl/certs which is also the default location on my Debian 6 server. Once I received the certificate from DigiCert I copied it to my home directory on the server then moved it to the /etc/ssl/certs directory and made it accessible only to the root user.
sudo mv /path/to/file/www_mydomainname_com.crt /etc/ssl/certs
sudo chown root:root /etc/ssl/certs/www_mydomainname_com.crt
sudo chmod 600 /etc/ssl/certs/www_mydomainname_com.crt
So now the certificate is in place. It’s time time set up networking. I now have two IP addresses on the server, I’ll call them 126.96.36.199 and 188.8.131.52 where 184.108.40.206 is the original IP that everything is configured to use. I use named hosts and use 220.127.116.11:80 as the host that all my sites run on. I’ll want the newly trusted SSL site on 18.104.22.168:443 and for convenience I’ll move the regular website to 22.214.171.124:80. But since DNS takes time to propagate I’ll want the regular site to listen on both IP addresses for awhile. Servers differ so your server may differ but this is how I did it.
1. Change the /etc/apache2/ports.conf file with configurations to listen on both IPs individually and both simultaneously.
2. Then for SSL I configure the SSL hosts as follows.
The NameVirtualHost *:443 statement is so that multiple sites can share an IP address with my self-signed certificate.
Then it’s time to edit the host file for the domain.
1. I change the <VirtualHost 126.96.36.199:80> statement to <VirtualHost *:80> so it runs on both IP addresses.
2. I change the SSL host statement from <VirtualHost *:443> to <VirtualHost 188.8.131.52:443> so it runs only on the new IP address. I will not be able to administer the WordPress site until DNS propagates but this isn’t a big deal.
3. I then add the necessary statements to the host file in order to enable the certificate:
The first two lines are the certificate and key files that I added earlier. That last line is the DigiCert intermediate certificate that needs to be added to the certificate chain. DigiCert provided the certificate when mine was sent. If I had multiple certificates from DigiCert they would all use this same certificate as the intermediate certificate.
5. Now it’s time to reload apache. At this point it will run the regular site on both IP addresses. WordPress administration (which uses port 443 for SSL) will only listen on the new IP address so I won’t have access to the admin console.
sudo /etc/init.d/apache2 reload
6. I update DNS to point the domain to the new 184.108.40.206 IP address. I wait a little while for the DNS to propagate. DigiCert has a tool that will check the certificate installation. I ran it and it confirmed a valid installation. I could access the regular site and the SSL site without a problem.
7. I wait another day to allow the DNS change to propagate and then I change the regular site to only run on the new IP address by editing the Apache configuration one more time. I change the /etc/apache2/ports.conf file to listen on both IPs individually but not simultaneously.
I remove the ability to list on both IP address for the regular websites. I don’t change the SSL port configuration.
8. Then I edit the site file for the domain so that it runs on the new IP address. I change the <VirtualHost *:80> statement to <VirtualHost 220.127.116.11:80> in the site file for the domain.
9. I reloaded Apache one last time.
sudo /etc/init.d/apache2 reload
At this point my trusted certificate is running on my website. I know longer get the untrusted site or invalid certificate warnings.
One benefit over the free certificates offered by some is that all my browsers already recognize DigiCert as a valid certificate authority that issues these certificates. No need to load another certificate in my browser.
While not a cheap process, it was surprisingly fast and easy.