Upgrading to HTTPS with WordPress, Amazon EC2, Let’s Encrypt and Cloudflare

If you’re a regular visitor to my website, have you noticed what’s changed?

I’ll forgive you if you don’t see it right away. You need to take a look in the URL bar, usually found at the top of your browser. You’ll see a green lock and, if you’re using the Google Chrome browser, a ‘Secure’ indicator.

Yup. I did it. I migrated the website from http to https.

Making this switch sounds simple enough, but it can get a bit complicated. I self-host my own WordPress website on an Amazon EC2 instance. I also use the Cloudflare CDN service to front my traffic to make the website a touch faster and to provide a thin layer of security.

While I am aware of straight forward methods to secure a website using Cloudflare, I wanted to use the Let’s Encrypt certificate service. I’ve heard a lot about it and figured what better way to learn how it works than to use it for my own website. For those not familiar with Let’s Encrypt, according to their words it’s a ” free, automated, and open certificate authority (CA), run for the public’s benefit. It is a service provided by the Internet Security Research Group (ISRG).”

I took on the challenge for the following reasons:

  1. I wanted to do my part to be a good citizen of the internet. Everyone who has a website should be using HTTPS/SSL to encrypt their traffic and protect the privacy of their users. I wanted to stop being one of “them.”
  2. I wanted to establish a more secure connection between my website and the Cloudflare CDN. Using their Full SSL implementation would have worked and been good enough. However, I wanted to go all in and use the most secure option available – Full (strict).
  3. While I could have used one of the Cloudflare SSL services and certificates, I wanted to learn about and support the Let’s Encrypt service. Plus, it gives me the option to move away from CloudFlare in the future without losing SSL.
  4. And last, but certainly not least, one of the reasons for self-hosting my website was to learn about running a server. What better project than upgrading a website from HTTP to HTTPS, especially a WordPress instance. It’s a perfect project to use as a learning vehicle.

Enough blabbering, let’s get started.

Background and references

Before I start a server project, I do my homework so I know the depth of the water before I jump. I did plenty of Google searches to learn about the experience of those before me. Here’s a list of the most useful articles I found. You’ll notice that there a few Amazon articles. They do a great job with their documentation. Their tutorials are very useful, and sure enough, they had a step-by-step on how to use Let’s Encrypt SSL certificates on an EC2 instance.

For informational purposes, this project took me the better part of a day (~6 hours). I would say the majority of this time was spent on research. Once I was comfortable and had my plan mapped out, creating the certificates, installing them, changing Cloudflare settings, and so on, only took a couple of hours.

The good news is that the server wasn’t down or offline during this time. The transition happens rather seamlessly to the site visitors.

Here’s the outline of my plan:

Disclaimer: The remainder of this article requires an intermediate level of server operation and knowledge. I’ve documented the steps well enough for my own purposes so I can update and/or recreate the SSL configuration on other websites I manage. 


Prerequisites

Before getting too far along, check to make sure that port 443 is open on the server and that the Apache SSL modules are installed and active.

  1. Login in to your Amazon EC2 console and make sure that port 443 is enabled for traffic in your security groups. Amazon has plenty of documentation on how to set it up.
  2. Install the Apache SSL module, if necessary. I’m using the Amazon AMI version of Linux, which uses the yum package manager. Run the following command:
    $ sudo yum install mod24_ssl
  3. Restart the Apache server to load the SSL module.

Generate and Install Let’s Encrypt SSL certificates

Step One: Create a backup snapshot of your Amazon EC2 instance, just in case.

I’m not going to detail the steps, just follow the Amazon tutorial: Creating an Amazon EBS Snapshot

Step Two: Check that Python is installed.

Run the following command:
$ yum list installed | grep python

If you don’t see any results for Python, such as ‘python27.x86_64’, then install Python as follows:
$ sudo yum install python27-devel git

Step Three: Check if Extra Packages for Enterprise Linux (EPEL) is enabled.

Run the following command:
$ yum repolist all

Look for ‘epel/x86_64’ in the resulting list. You will see ‘enabled’ to the right of it. If not enable it as follows:
$ sudo yum-config-manager --enable epel

Reference: AWS – Adding Repositories

Step Four: Download the latest release of Certbot from EFF and make it executable.
$ wget https://dl.eff.org/certbot-auto
$ chmod 755 certbot-auto

After downloading Certbot, you might want to put in a directory other than where it was downloaded. Just remember where you put it because you will need the location to setup the automation later.

Step Five: Run Certbot to generate the SSL certificates

Since the site is running on Cloudflare, you will need to run a couple of special options. Specifically, you need to run it with the ‘certonly’ option, and you need to verify site ownership using the ‘webroot’ flag. Unfortunately, you can’t use the interactive method. You’ll need to move and edit a few files later.

$ sudo ./certbot-auto certonly --debug --webroot -w <path_to_website_root> -d example.com -d www.example.com --agree-tos

Step Six: Update virtual host entries and restart Apache

The good news, you have the certificates. Now you need to update your virtual host entries to point to the newly minted certificates. I’m not going to list the steps here since they are different depending on your configuration. I’d recommend using Nowland’s or Petkov’s articles that I referenced above.

Once the virtual hosts are updated to point to the certificates, restart Apache. Take a deep breath and relax. You’re almost there.

Step Seven: Update CloudFlare settings

The site is ready to accept secure connections from Cloudflare. Go into the Cloudflare settings for your website. Find the icon labeled ‘Crypto’ and click on it. The first settings entry is ‘SSL.’ Select ‘Full (strict).’ You can do this because you have a valid certificate that Cloudflare will honor. Cloudflare will serve your website using their SSL certificate, but all requests for content that are made to your website will be over an SSL connection.

Cloudflare - Crypto settings for SSL


Update WordPress and Cloudflare settings

For these steps, I relied heavily on the article by Bramus that I listed in the reference list.

Step One: Change default domain name

In the WordPress General setting tab, change the ‘WordPress Address (URL)’ and ‘Site Address (URL)’ to an https prefix.

Step Two: Force SSL for admin

This step involves making an edit to your wp-config.php file. It’s not mandatory, but since you’ve went through the work to enable HTTPS, why not? Just add the following line to the file:

define('FORCE_SSL_ADMIN', true);

Step Three: Redirect all requests to HTTPS

This is step #5 in the Bramus article. It involves making a change to the .htaccess file such that all requests into your website are forced to use the https domain. Here are the directives to add to the file:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Step Four: Enable HSTS (in .htaccess)

This step isn’t absolutely necessary either, but you might as well since you’ve come this far. It’s just good practice to do it. By the way, this is step #6 in the Bramus article.

# Enable HSTS
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains" env=HTTPS

Step Five: Enable HSTS in CloudFlare

Since we’ve went through the trouble of adding HSTS to our website, let’s go ahead and enable it in Cloudflare. Go back to the ‘Crypto’ settings for your website in Cloudflare, head about halfway down the page and locate the setting ‘HTTP Strict Transport Security (HSTS).’ Chose ‘Change HSTS Settings’, acknowledge the terms, select ‘Next’, and then enable it on the final screen. I just used the recommended defaults.


Automate certificate renewal

Let’s Encrypt SSL certificates expire after 90 days. Thankfully, you can setup certbot to check for your certificates daily and renew them automatically. It involves creating a cronjob on the server. Both Amazon and Cloudflare have support articles on how to do it. Here are the steps that I followed.

Step One: Open crontab

Open up crontab to add the renewal job. It’s easy, just open the file /etc/crontab in a text editor on the server.

Step Two: Create the cronjob

In my case, the crontab had easy to follow instructions for setting up a cron job. Some places suggest checking twice a day for updates, but I figured once was enough. It’s also a good idea to restart the server if and when the certificates are updated using the ‘deploy-hook’ option in certbot. Here is the line I added to my cronjob:

3 4 * * * root /usr/bin/certbot-auto renew --deploy-hook "service httpd graceful"

Step Three: Restart crond service

Restart the crond service, and your automation is ready to go.
$ sudo service crond restart


Fix mixed-content warnings

Now that you have everything running, let’s reload the website. It’s possible that you see an ‘i’ (info icon) instead of the green padlock. This means you have mixed-content warnings. In other words, not all of the content on the page has an https prefix. It’s usually due to old links that are in the WordPress database.

The Bramus article has scripts that you can run on your database to update all of the links in your database. I had prepared myself to take this step, which had me feeling very uneasy (editing the WordPress database directly always gives me the heebie-jeebies). Thankfully, the power of Cloudflare saved my bacon.

If you go to the ‘Crypto’ settings for your website in Cloudflare, there is a setting halfway down the page called ‘Always use HTTPS.’ Turning this to the ‘on’ position will cause all of the links on your page to magically go from ‘http’ to https. Of course, if you want to be complete, you can run the database scripts. In my case, after flipping the switch, all was good. I decided to leverage the Cloudflare setting and leave my database as is. My motto: The less mucking with the WordPress database, the better.

I can always revisit this later if the Cloudflare settings change, or if I decide to stop using the Cloudflare CDN service.


Inform Google you’ve went secure

Now that we’ve completed all of the work to enable HTTPS, let get credit for it from Google. Google has been telling us that it will favor HTTPS websites, so we should take advantage.

Step One: Change the domain in Google Analytics from http to https

I’m going to assume that you’re using Google Analytics and have it enabled on your site. If so, login to your Analytics account and change the default URL to ‘https’ in both the Property and View settings.

Step Two: In Google Search Console, add the https version of the website

Google Search console is a hidden secret that you need to be taking advantage of, if you’re not already. Head over to the Search Console (click here). Click the red ‘Add a Property’ button and follow the instructions. Just be sure to use https in front of URL. Now you can get statistics from Google regarding how it sees your website. It also helps alert Google that you’ve gone secure.

Step Three: Add a sitemap.xml if you have a sitemap for your WordPress instance

Now that Google knows about the https version of your website in Search Console, submit a sitemap. This will tell Google what the structure of your website looks like and how to index it. It’s under the ‘Crawl’ menu in Search Console. Find the sub-menu ‘Sitemaps’, click on it, and then follow the on-screen instructions to test and submit a sitemap. There are great WordPress plug-ins to generate one, including the popular Yoast SEO plug-in.


Validate SSL settings

The final recommended step is to check with a couple of third party website to make sure they agree with your HTTPS setup.

Step One: Enter your domain at the Qualsys website (click here)

If you run into any problems, errors, or warnings, the website should give you suggestions and recommendations on how to fix them.

Step Two: Check with SSL Shopper (click here)

This isn’t entirely necessary. I figured it would be good to see the results from more than one source just to make certain that independent parties agree that my website is secure.


Congratulations! If you made it this far, you did it. You’re website is now HTTPS secure. You’ve done your part in being a good citizen and steward of the internet.


Disclaimer #2: I documented these instructions for my own personal use in case I need to reference them later to remember and recreate what I did. You are more than welcome to reference my experience, but keep in mind that they may or may not work for you depending on the specifics of your setup. What I’m trying to say, in not so many words, is that I’m happy to entertain questions and will do may best to offer assistance, but I cannot guarantee timely and accurate responses.

 

Share on: Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInEmail this to someone