With the advent of Let’s Encrypt, introducing free and easy SSL certificates for everyone, and the fact that Plesk, cPanel, and home grown Panels like DreamHost’s all providing easy ways to install certs, renew them, and support them, we’re finally inching our way to the dream of HTTPS Everywhere.
Why HTTPS?
The S makes it secure, and the green lock on a browser tells a person that their visit is safer, encrypted, and obscures sensitive data. It means a visit is confidential. It means the site is the real site. It cannot be easily monitored, modified, or impersonated.
While this blog has no sensitive data of yours, it does accept (require) your email when you leave a comment. You don’t want everyone knowing that, I suspect. You probably don’t want everyone grabbing your IP.
Why do we care about security in general? Because nothing is non-sensitive anymore. Everything we do and say on the Internet can be used against us. Entering in your mother’s maiden name on a form over HTTP? Someone can snipe that and use it to steal your identity. Use the same password on multiple accounts, one of which is HTTP? Your code can be stolen. The list goes on and one.
How I Turned This Site HTTPS Everywhere
Every single domain on ipstenu.org
is now https. Everyone either has the Let’s Encrypt certificate or a Comodo one. First I turned on Let’s Encrypt. Then I used WP-CLI to search and replace my urls:
$ wp search-replace http://halfelf https://halfelf $ wp search-replace http://ipstenu https://ipstenu
And so on and so forth down the line.
Next I checked my mu-plugins
folder and my content
folder to make sure none of my home grown code was hardcoding in http (it wasn’t), and updated my wp-config.php
to include this:
define('FORCE_SSL_ADMIN', true); define('FORCE_SSL_LOGIN', true);
That probably wasn’t required but why not? Finally I tossed this into my .htaccess
:
# Force non WWW and SSL for everyone. <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC] RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] RewriteCond %{HTTPS} off RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] <IfModule mod_rewrite.c>
Really. That’s all it took to swap it all to https everywhere here.
Gotchas
Not all my plugins were happy about this.
Most were, actually, which was nice, but a couple did some incredibly stupid things with hardcoded http
resources. Fixing them for myself is trivial. For others… I recommend WordPress HTTPS or Really Simple SSL, both of which will let you force https for all URLs or block the http ones.
For the most part, with WordPress, you don’t need to worry about this. In recent years, the ability to force SSL from within WP itself has gotten better and better. The problem has always been our themes and plugins.
Other than that, it’s been pretty smooth going.
Non WordPress
But… what about my non-WordPress sites? Yeah, you know I have them.
Well my ZenPhoto20 site doesn’t run any extensions, so I just checked the box for using SSL and went on my way. I’d cleverly written all my themeing with protocol-less URLs (\\example.com\my\path\file.css
). While that’s really an anti-pattern, and https should be used whenever possible, I had everything in one file so I search/replace’d that and it was done.
My Hugo site required two changes to a config file. It looked like this:
StaticURL = "https://example-static.net" HomeURL = "https://example.net"
The reason I did that was so my templates could look like this:
<link rel="shortcut icon" href="{{ .Site.Params.StaticURL }}/images/favicon.ico">
Once I saved the variables in my config, I could push the site (which automatically rebuilds and deploys) and be done.
Comments
9 responses to “Making HTTPS Everywhere”
I’m reading this on my phone so I may have missed it. ?
Don’t Forget to set the header for HSTS. It’s really easy to do and browsers will honor that setting.
https://en.m.wikipedia.org/wiki/HTTP_Strict_Transport_Security
Jan, HOW would I set the header for HSTS?
@Bet Hannon: see https://halfelf.org/2014/hsts-chromium/ and https://halfelf.org/2014/ssl-for-one-domain-on-multisite/ π
@Bet Hannon: Due to many people asking me about this, I’ll have a blog post about it soon. Because ANSWERS!
@Jan Dembowski: I had to do that a long time ago when I was turning on https for the store.
I’ve had to submit patches to themes and plugins in the past because they were hard-coding http://fonts.googleapis.com and not using //fonts.googleapis.com.
In Chrome the fonts weren’t loading cause it complaining that I was pulling resources from a non-secure domain.
I’ve drawn from examples at https://codex.wordpress.org/Administration_Over_SSL – in particular the bit that goes:
“An important idea in this block is using THE_REQUEST, which ensures only actual http requests are rewritten and not local direct file requests, like an include or fopen.”
…and also, the idea of using QSA flags… thoughts?
Further, wondering if you have thoughts on setting
define('PROTOCOL', 'https://');
in wp-config?
Perhaps its also worth mentioning use of
define('FTP_SSL', true);
as well.
Also, it seems that
FORCE_SSL_LOGIN
is now deprecated (since 4.0) in favor of only usingFORCE_SSL_ADMIN
.Thanks very much for the write up =)
@Max: I cleaned up your post with pre and code tags π
I have other blocks in my .htaccess for requests and the like, so for ME it’s not really an issue. Ditto ftp-ssl, since there’s no non ssl ftp on the server.
Nice explanation! Very useful!