Those of you who pay attention to such things (and, realistically, most of the people who read this blog are tremendous nerds about one thing or another) may have noticed the exciting green secure HTTP padlock to the left of the URL in their browser bar.
Yes, we’re now officially just as secure as a 3AM Donald Trump tweet about Saturday Night Live is insecure.
The adventure starts here
Not entirely unrelatedly, some of you may also have noticed that this blog disappeared for several days, my glorious content replaced with a dystopian hellscape of Too Many Redirects and Infinite Loop errors, because it did. Others of you may not have noticed this, because it didn’t. Extremely mystery, wow.
It makes it a lot harder for someone to steal my login/password, for people to infect this site with spam links, for someone to pretend to be this site in order to confuse and bamboozle you, or for dodgy ISPs and hotel connections to stick ads and pop-ups in the middle of your browsing.
It also means that nobody snooping on your connection can see what you’re doing here (they can still find out that you’re doing something on this server, but they have no idea whether you’re reading decent honest posts about IT security or downloading the secret archive of filthy dog porn).
Finally, because of all the above, search engines give SSL sites better rankings.
If you run a website, even one as modest as this one, you should move to SSL. You can get a certificate for free, which is extremely easy to deploy with most major hosting companies, or onto your own server.
“But John“, you may well ask, “if it’s so easy to deploy, then why did your blog disappear for several days to be replaced by a dystopian hellscape of Too Many Redirects and Infine Loop errors?”
Well, that’s a very good question and I’m glad you asked me it…
The start of the nightmare
The short answer is that the last WordPress website I installed SSL on (a work client’s, rather than one of my own) used a different hosting architecture from this site, and so trying to follow the same steps broke everything. And also that computers are bastards, so when I thought I’d fixed everything a week ago, and again yesterday afternoon, that was only true for a random subset of people.
And when I say “random”, I mean “bafflingly random, and I’m still baffled”. There was a point where the site would load successfully in a clean browser on my mobile phone over my home ADSL/wifi connection, but triggered the infinite loop error in the same clean browser over a 4G connection. THAT DOESN’T EVEN MAKE SENSE.
The longer answer, which may be of use to people in the depths of Googling similar problems, is that my client’s hosting company is a conventional internet shared hosting provider, whereas this site is much more cloud-based, and I didn’t pay enough heed to the difference.
Secure hosting, old-style
My client’s hosting company give you a directory on a Unix/Apache server, a MySQL control panel, and so on; you configure it all and install applications, and it either works or breaks. If you want to use a CDN/cloud provider, you need to sort one out yourself. Traffic there is well within bandwidth limits at the moment, so I haven’t set this up.
The client’s site has more legacy issues than Bleak House, so there was a lot of work involved in manually converting hardcoded HTTP to HTTPS in links (especially for externally-called scripts, where it was entirely unclear whereabouts in the bloated database the hard-coding was stored).
Getting this conversion done before you switch the site over isn’t just a case of tidiness.
For obvious reasons, it’s far far worse to have a website which looks secure but isn’t, than to just have a website which isn’t secure. Because of this, if your HTTPS website tries to load insecure content over HTTP, then your browser will tell it to get stuffed.
In some cases, this will mean the user gets a plain-looking site that’s missing scripts, fonts or stylesheets – in others, they will get a blood-curdling “this is insecure and people will steal all your data” error message. Neither is a good look.
This meant that by far the best migration option – switching fully TTP to SSL over a weekend and immediately redirecting all HTTP links to HTTPS – wasn’t viable: I didn’t have time to migrate the scripts. Instead, I took a half-arsed (although still better for the client at all times than having standard HTTP) route.
All the WordPress sites I manage use the iThemes Security plugin. It’s good for various anti-hacking reasons if you run anything on WordPress, but also features some simple options for selectively migrating to SSL without having to mess with low-level coding.
In particular, it meant that I could protect the site admin area with SSL and also encrypt user signup forms, while I worked out how to switch the rest over without buggering up functionality and appearance. Eventually I did, and the switch was made, and now everything is good over there. Hurrah!
The shock of the modern
Anyway, this reminded me I should really migrate this site over to SSL, so I did. I got myself a free certificate, did a one-click install on the server at Dreamhost, changed the WordPress site details and iThemes settings to use SSL… and everything disappeared straight into a mire of infinite loops and server errors.
The problem is, Dreamhost uses a very different model from the other provider. Presumably as a defence from the obvious threat to conventional of people going generally towards The Cloud, they’ve repackaged themselves as a cloud services aggregator, so you don’t need to arse about with external content delivery networks and suchlike. Basic Cloudflare services are included in hosting packages, and upgrading to heavier-duty ones is rolled into your billing system.
I enabled Cloudflare on this site a while back after a spam attack, which means that it no longer behaves like a simple Unix-server-hosted website. So the one-click server install I did above wasn’t just installing a certificate, but also installing and switching on Cloudflare’s built-in HTTPS security suite. This didn’t play nicely with WordPress.
Luckily, there was a quick fix – Cloudflare has built a Cloudflare for WordPress plugin, especially designed to avoid this kind of arsery. And after I installed it, everything recovered – the site was forcibly redirected to HTTPS, there were no mixed content errors, and no evil infinite loops. Hurrah!
I celebrated the only way I know how – by pouring a big glass of gin and writing a blog post about UK by-election polling.
A little charm and a lot of flare
But the euphoria was tragically short-lived. Not long after tweeting the link, I got several replies saying the site was still throwing infinite loop errors (well, they were neither psychics or spies, so it was my brain that added the ‘still’).
Everything still worked from my computer and phone on every conceivable browser, so I was a bit sceptical at first – I thought it was some combination of legacy cached data and weird old browsers; then @richgreenhill sent me a link to a security testing site called Security Headers, which (at the time) also showed an infinite loop. Curses.
After a great deal of playing around with Cloudflare, WordPress and iThemes Security settings, the infinite loop eventually finally disappeared from the Security Headers site when I disabled iThemes. Even better, after I reinstalled iThemes, the site continued to show up on Security Headers (and yes, it was showing a live version – I spent a while improving my score there, and the changes I made showed up directly). So I tweeted that everything was fixed; hurrah!
But it wasn’t.
A bunch of people – including everyone who’d previously reported problems – and the Google Plus sharing tool still got the infinite loop error (Feedly and LinkedIn sharing were fine). When I switched off the wifi on my phone and used the 4G connection, I also got the error (and yes, I was then able to switch the wifi back on and view the site in the same browser window, then switch it off again and go back to the infinite loop).
Eventually I fixed the problem by turning off all SSL support in iThemes Security, because the Cloudflare master setting to redirect all HTTP requests to HTTPS was all I needed, and it was clearly those two levels of redirect that were clashing. As of now, everyone who’s previously reported problems can see everything, and the same’s true for automated sites. The migration seems to have finally been successful, and I don’t need the page-by-page restrictions that iThemes provides.
Ongoing bafflement, or ‘be more like John B’
I’m still a bit confused though.
- Why didn’t turning off Cloudflare’s “automatic redirect to https” setting and purging the cache (to rely on the iThemes setting) do anything?
- Why did Security Headers initially see the redirect loop and then see the website, even though that fix didn’t work for anyone else?
- What on earth is the difference in network processing that would lead to me getting different results on the same device in the same browser over a 4G versus wifi connection (both are IPv4 in case you were wondering – I did look into this earlier).
If you’ve got any thoughts, let me know in the comments or tweet me or send me a carrier pigeon.