I just finished installing my first-ever SSL certificate by hand. While it wasn’t exactly fun, it wasn’t as harrowing as I expected it to be. Of more value, I learned about some helpful tricks and resources, which is why I put myself through this process.
Before I share those details with you, let me clarify something about me. While I’m considered “one of America’s foremost cybersecurity experts,” my expertise isn’t hands-on. I’m not one of those guys who flings conf files and hacks router bits. What I do is stand in front of a virtual classroom and scare the pants off of generals and admirals, CEOs and whatever CXOs are this week. I’m real good at giving leaders reasons not to sleep, but I don’t really enjoy setting up servers and networks.
Oh, I force myself to do it. That’s part of why I’m coding and doing these side projects. I don’t ever want to become one of those people who look at you blankly when actual technical things come up. That’s why — instead of just paying someone to set up SSL on a server for me — I did it myself on my own little Linux install. It’s how I keep my chops up and how I maintain a clue. It’s also how I discover cool stuff that doesn’t necessarily show up on PowerPoint slides.
I’m doing this project because PayPal is about to become all SSL and that’s going to impact my Seamless Donations users. As of last week, the PayPal sandbox requires SSL-based https URLs, so folks are going to have to come up to speed with SSL quickly. Now, let’s be clear. This is a scary world, and secured Web sites are important. It’s getting to be way past time that it’s safe to log into the WordPress dashboard with just http.
Aside: I once had a discussion with the former Supreme Allied Commander in Europe (SACEUR). You know what he told me? He was a lot less afraid of Russian tanks than he was of hackers. Tanks were manageable. Hackers were terrifying. Keep that in mind. This is a guy who commanded more than three million soldiers and he was more worried about folks in sweatpants and T-shirts.
So let’s get back to SSL. I started by setting up a LAMP droplet (basically a virtual instance) at Digital Ocean. That’s Linux, Apache, MySQL, and PHP and Perl (with some other stuff thrown in for good measure). I installed WordPress on the site (but haven’t yet https-enabled that site) and downloaded and installed Seamless Donations. I established an SSH connection and was ready to go.
Getting an SSL certificate
This was going to be a test machine, so I didn’t really want to spend a hundred bucks on a commercial SSL certificate (it turns out you don’t have to.. stay tuned). Instead, I thought I’d try out Let’s Encrypt, which is a free SSL certificate authority and client supported by the Electronic Frontier Foundation. I did the appropriate gits and wgets, but ran into all sorts of snags getting the client to work. Given that Let’s Encrypt is still in beta, I decided it wasn’t going to be something to recommend to production nonprofits, so I decided to move on.
While many of you complained to me over the weekend that SSL certificates are expensive, it turns out there are some great, low-cost alternatives. The one I took advantage of was a $9 single-domain SSL certificate from namecheap.com (no, that’s not an affiliate link — I don’t get anything from the recommendations in this post or in any of my links from anything I write). What I liked about the certificate, which is why I went with NameCheap is that NameCheap is only a reseller. The certs themselves come from Comodo, a very well-respected certificate provider.
You basically buy the certificate like you do a domain name. You create an account, enter name, credit card, and so forth, and you’re taken to a form where you then need to provide a pile of encrypted data. That’s where things got interesting.
Command-line fun
So here’s where I give you some advice. If you like setting up servers, tweaking files in /etc, looking up command syntax and typing out command lines in a shell, then you’ll have no problem (or, no more than the usual problems) setting up SSL like a man. But if you’re more like me, and would really prefer to delegate, setting up SSL for your site will be much more about talking to your hosting provider and probably paying a small fee. Note that for my main Web site, I will be asking my hosting provider to do the heavy lifting.
But for a development site, I did it all by hand. Basically, you need to type in a few arcane command lines that give you a private key and a CSR (which is a certificate request). You keep the private key private, and give the CSR file to the certificate authority, who then makes you a certificate. If you ask your host for help, they’ll either create a certificate for you or give you the CSR file which you can take to someone like NameCheap.
Once you deliver your CSR file to your certificate authority, you have to verify that you’re you. You can use email, put a funny little file on your Web site, or add a CNAME to your domain name zone file. I chose the latter because I’m cool that way. Eventually (about 15 minutes in my case), the certificate validation process will complete. Shortly after, I got the certificate file as a ZIP file in my email.
At that point, I used SFTP to put the certificate file on my server and then set up a virtual host in Apache that responded to port 443 (the main port 80 equivalent for https). I ran into some syntax snags here, editing my virtual hosts conf file with the proper commands for SSL, but eventually I got it right. After about 20 attempted restarts of Apache, the server started.
Tools that helped out
I used two tools that really helped out and resolved some issues. The first was that I kept getting errors that implied my private key file was invalid. I didn’t think it was invalid because, by this time, NameCheap had issued me my valid SSL certificate, but still, that’s what all the Google search results seemed to say. At first, I thought it was a permissions issue (always the go-to nightmare in Linux configuration). So I set my private key file to 777 (making it visible to everything). Since I still got the error, I knew it wasn’t permissions. So I set the permissions back appropriately.
But I still wasn’t sure if the private key was valid. Everyone online seemed to think that if you got the error I got, the file was corrupted. As it turns out, there’s a nice little validator out there at SSLChecker.com that checks to see if your private key matches with your official certificate. Now, I can’t really vouch for how smart it is to upload your private key to some site on the Internet for validation, but since this was for a dev machine that would never move actual money, I wasn’t concerned. It confirmed my private key was valid.
So that meant that (a) it wasn’t a permissions issue and (b) it wasn’t a corrupted private key, so that could only mean my configuration was wrong. It was. I needed to also provide the bundle file along with the certificate and the key. Here’s my virtual hosts configuration for security (I put all my certs in /root, which is convenient, but I wouldn’t recommend doing it for a production server):
SSLEngine on SSLCertificateFile "/root/ssl/mydomain_com.crt" SSLCertificateKeyFile "/root/ssl/mydomain_com.key" SSLCACertificateFile "/root/ssl/mydomain_com.ca-bundle"
Finally the server started up. And that’s where the next resource came into play. Did this actually work? I did go to the https equivalent of the URL and the little green padlock showed up, but I wanted deeper confirmation. There’s an SSL checker that does a nice scan of your install, and lets you know if everything’s working. I used that, and everything was, in fact, working.
So there you go. My first SSL certificate installed. Next, I’ll do the basics to enable SSL in WordPress and take a look at how that works with Seamless Donations. But that’s a project for another night.