Select Page

My history with building websites and book marketing is like a random walk wearing a blindfold. Try something, do it wrong, fix it, move on to the next mistake. And that’s why I originally built this website with HTTP instead of HTTPS.

A few people challenged me on this recently. Why did Google Chrome insist my website was insecure, and how can somebody who claims to be a cybersecurity professional run an insecure website?

They’re right. HTTPS websites are safer than HTTP websites. Dialog with HTTPS websites is encrypted, and HTTPS websites advertise a certificate signed by a trusted certificate authority that says the website is what it claims to be. This isn’t a big deal with online brochures, but it’s vital when the website asks for personal information. And, so when I added my opt-in page and asked people to share email addresses with me, it was time to change to HTTPS.

Here is how I did it.

Whenever I try something I haven’t done before, I always look for how-to writeups. I found plenty. Here are a few.

They all had valuable information, but none gave a complete picture. And so I decided to share my experience.

Set up a certificate

Digital certificates are at the heart of every HTTPS website. The words, “digital certificate” scare people, and lots of technology and complex math is behind it, but the concept is simple. Assume Alice wants to visit Bob’s website. How does Alice know Bob’s website really is Bob’s website and not an imposter? If Alice and Bob both trust Cathy, and Cathy says Bob’s website is good, then Alice believes her. That’s the concept.

Here is how it works. Before Alice visits Bob, Bob must first convince Cathy he really is Bob. Once Bob proves himself, Cathy will sign a certificate attesting Bob really is Bob, and give a copy to Bob. When Alice visits Bob’s website, Bob will show Alice the certificate. When Alice sees Cathy signed it, and since Alice trusts Cathy, Alice will also trust Bob.

Cathy is called a certificate authority, or CA, and we use this technology every day when we buy and sell electronically. Here is a presentation with more about how trust on the internet works.

My first step to HTTPS safety was finding a CA and getting a certificate.

I chose a CA named LetsEncrypt. Let’sEncrypt presents itself as a free, automated, and open certificate authority, run for the public’s benefit by the Internet Security Research Group (ISRG). The most influential open source organizations in the world sponsor ISRG, which makes it a credible alternative to the paid services. Sometimes, free is worth less than what we pay for it. But in this case, free (as in beer) is good.

Installing certificates has always been a hassle and was one of the reasons I took so long to make it happen with my website. Enter a tool named certbot from the Electronic Frontier Foundation (EFF), one of the ISRG sponsors.

I need a paragraph of background information. As of this writing in June, 2019, I operate my website from a Red Hat Fedora virtual machine in my basement. I look forward to the day when I need to move it to a commercial hosting service, but until then, I have the whole virtual machine to myself, which means I can set it up any way I want.

Details will be different if I use a commercial hosting service, but for now, install certbot like this:

dnf install certbot certbot-apache

And then run it by typing:

certbot

and go through the dialog. We want a certificate for www.{domain}.com. The dialog sets up another httpd config file with an HTTPS virtual host for the domain in question. The certificates expire every 60 days, and so we’ll want automation to keep them updated. Use the “certbot renew” commnad to check the age of the certificate and issue a new one when the old one is close to expiration.

Automate that renewal check by setting up a cron job. An example cron job might look like this, which will run at noon and midnight every day:

0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew 

Make sure the hostname matches the certificate. If the certificate is for www.example.com, do this:

hostnamectl set-hostname www.example.com

Update http references to https in the database

With the certificate in place, login to the website as wp-admin and go to settings…general. Update the WordPress Address (URL) and Site Address (URL) fields to use HTTPS instead of HTTP. This will force a logout; log back in to the new HTTPS website.

For multisite websites, the WordPress Address (URL) and Site Address (URL) fields might not be visible. To work around this, install the “Better Search and Replace” plugin from https://wordpress.org/plugins/better-search-replace/. Use it to replace all occurrences of http://www.example.com and http://example.com with https://www.example.com, matching the certificate you installed above. This might take a few passes but should do the trick.

If the “Better Search and Replace” plugin from above has problems, try the Velvet Blues Update URL plugin. Install the Velvet Blues Update URLs plugin, activate it, and change occurrences of http://www.example.com and http://example.com to https://www.example.com.

Edit wp-config.php

Edit /etc/wordpress/wp-config.php and insert this line above where it says “That’s all, stop editing!”

/* Force admin logins to use https */
define('FORCE_SSL_ADMIN', true);

Work on mixed content

Custom menu items and external links in blog posts and pages might also have HTTP links instead of HTTPS links. Some links built into themes might also be HTTP instead of HTTPS. Use the “Better Search and Replace” plugin and view…source on web pages to ferret these out. Iframe links to Youtube need to update from HTTP to HTTPS.

Update the backup script

I run a backup script in a cron job every day to backup my WordPress database and all my content. But after engaging with LetsEncrypt, I need to also make sure I backup the directory, /etc/letsencrypt. I modified my backup script, named backmeup.sh, like this:

Before:
echo "Copying /etc/wordpress/"
rsync -a /etc/wordpress/* ${TGT}/etc/wordpress

After:
echo "Copying /etc/wordpress/"
rsync -a /etc/wordpress/* ${TGT}/etc/wordpress

echo "Copying /etc/letsencrypt/"
rsync -a /etc/letsencrypt/* ${TGT}/etc/letsencrypt 

Redirect everything to HTTPS

I needed to modify a few config changes by hand. Certbot put these changes in the bottom of /etc/httpd/conf.d/example.conf.

.
.
.
RewriteCond %{SERVER_NAME} =www.dgregscott.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

But that only redirects the main website. The other pages can still display via HTTP. To redirect everything from HTTP to HTTPS, modify it like this:

.
.
.
##RewriteCond %{SERVER_NAME} =www.dgregscott.com
##RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

Redirect permanent / https://www.dgregscott.com/

And that should do it. Sooner or later, everyone with a website will need to go through a similar exercise.