Hopefully you noticed the nice little green icon in the URL bar above:
On a whim I decided yesterday afternoon that it was time to switch to https for my blog. It turned out to be a multi-hour task, but all in all, not too terribly difficult. Here is how I did it. To be clear, I may not have done it the best way, but this is what worked for me and it seems to be rather stable, so I'm satisfied.
Getting the Certs
First I needed to get my certificate. I started with Let's Encrypt, a free command-line driven tool to generate https certificates. I was a bit worried about this solution for two reasons. First, this warning made me a bit nervous:
Let’s Encrypt will issue a limited number of certificates each week.
I wasn't necessarily worried about getting the initial certificate, but I was worried about renewing that certificate. What if I couldn't get a new certificate in time? Maybe that was a silly thing for me to be worried about, but I just couldn't get over it.
That tied nicely into my +second+ concern which was the fact that their certs expired every 90 days. Not only would I have to ensure I scheduled time to update the certs, I'd have to worry about actually being able to get the cert when it was time.
I did take a stab at using Let's Encrypt, and when I ran into trouble making it work with Surge, I decided to just move on. Let me be absolutely clear - I greatly appreciate what Let's Encrypt is doing here. They should be applauded. I'm sure if I worked on it longer I would have gotten things working, and as I said, my concern over renewing was probably overblown, but ultimately I found SSLMate much easier to use.
SSLMate is also command-line driven, but not free. Each cert costs 16 dollars per year which seemed pretty cheap, especially since my host charges in general are pretty low now.
Updating the Site
Once I had my cert, I simply followed the Surge docs on SSL and it worked so quickly I thought it was broken. I had https running fine on my blog (www.raymondcamden.com), but that left one big issue - all of my images are on an Amazon S3 server, static.raymondcamden.com. If you mix https and http assets on the same page, you'll get a warning in your console and you won't get the friendly seal of approval with the pretty little green lock.
Why do I use both S3 and Surge? Well, that's a bit of a long story. Basically Surge has to push my entire site whenever I add new content. I've got 5.5K blog entries and a crap ton of media associated with those posts. While Surge is working on a rsync-based approach, right now it is has to push everything. For my blog, that meant an approximately 15 minute deployment when I blogged. Not the end of the world, but a big long. I decided a few weeks back to move my images to S3. This meant another certificate purchase of course.
While S3 supports https natively, it does not support it for a custom domain. In order for that to work, you have to use Amazon CloudFront to proxy your bucket and handle the certificate from there.
It is... complex. Surprisingly so. I used this blog as a guide: Implementing SSL on Amazon S3 Static Websites. My biggest struggle was the damn command line to upload the certificate. I suppose a simple web-based solution would be crazy (and maybe one exists), but I spent a majority of my time just trying to get one particular command line working.
Once it did, I then found out how slow CloudFront is. It took about 30 minutes for it to properly set up and work correctly, and then I discovered how aggressively it caches content. To be clear, this is expected, and isn't a bug, but it was a surprise. To replace existing content and have it show up immediately, I need to go to my CloudFront console and create an invalidation request. In my test, it took about 15 minutes to replace cached content. Amazon actually recommends just adding a new asset with -1, -2, etc in the name, which feels lame, but has the benefit of working immediately.
Again - this is all how it is supposed to work, but was part of my learning process in getting things set up.
As a final nit, Surge asks you to do one small mod to your deployment in order to force all http requests to https. Oddly, I didn't seem to need this. I would request the http version and Chrome, Firefox, and Safari all loaded the https version. After speaking with Brock Whitten on the Surge slack, he mentioned this may just be the default behavior of newer browsers. He checked with curl and http was still served that way. So the final, final step was one small change to my build script to tell Surge to push only to https.
Conclusion
And that's that. In my informal testing on Twitter, everyone said it was working correctly except for one user who said they saw an issue on an Android device. If anyone else can confirm that, I'd appreciate it. Otherwise, let me know if I can answer anything else about my process by leaving a comment below.
Archived Comments
I was thinking of checking out LetsEncrypt, but I didn't see that fine print. Also, you have to do some leg work to get it working with Nginx, which isn't a huge deal, but meh. It is supposed to be possible to renew the cert with the LetsEncrypt shell scripts and crontab so it will "automagically" renew.
I realize that won't be an issue here, but just putting it out there. :)
Ray - btw if you use CloudFront, Amazon provides SSL certs for free for your own custom domains, it is super easy to setup and they handle the private key storage, etc. Checkout https://cfdocs.org/ as an example.
Also with CloudFront you can control how long things are cached for by using Cache-Control headers, but the whole idea is that you would be caching most of your content there. I'm not sure how your blog is setup these days but you can also tie in S3 events to trigger invalidation requests. Yes the invalidation is not instant but you can make it automatic via their APIs with a little glue.
Yeah, I definitely felt that LE would be "possible", but I didn't want to spend much more time on it.
free cert: Well shoot, I didn't know that. Luckily it was only 16 bucks, so not too big of a deal. To be honest, I didn't mind spending the money, it just bugged me how weird it was to get the damn cert up.
cache controls: Yep, I kinda learned that a bit when I first tried to update something. :) It all kinda makes sense - but it was a big surprise. In general, I will *rarely* update stuff.
They are "free" but you pay more (1/4 penny more per 10k requests) for HTTPS requests on cloudfront, so they get ya!
More info about the amazon certs here: https://aws.amazon.com/blog...
Well, I'm going to be paying that anyway. I'm currently at about 6k page views per month - if you assume 4-5 images per page view, that's about 20k impressions per month.
One thing I forgot to mention and I should have - Amazon has a feature where you can get an alert if your bill goes over a threshold. I set one up just for that purpose.
another way to get free ssl is to use cloudflare...
I'm having trouble getting Let's Encrypt X3 to work with cfhttp get on CF 11. I used keytools to import the ISRG, DST and Let's Encrypt X3 certs into the castore, but I'm still getting "unable to find valid certification path to requested target".
Do you experience that as well?
I'm not using CF at all for this blog. Last time I had to use a cert w/ cfhttp it was a pain - but it worked. But it was a few years back. Sorry I can't help.
No, HTTPS-first is not the default behavior of modern browsers. You should enable HSTS preload and continue to serve HTTP/301s for non-secure requests.
Ok, then how do you explain what I saw? Note - afaik - now all requests should auto 301 to https.
It should be noted that the 90 day expiry is actually a security feature. You want certificates to expire sooner. This narrows the window of how long a certificate is available for cracking or if a key were leaked your exposure is limited. Certificate revocation checks are limited and that 90 days is better than 365.
Also the 90 days effectively means you need to automate the process. Rather then once a year having a half written note about the process.
The Let's Encrypt scripts I have used auto-renew at 60 days, a daily tasks checks the age and then if it's over 60 it will renew the certificate, so there is plenty of time to make sure it stays up and running.