Editor’s note: This blog post was updated on June 27, 2018.
Every couple months or so, Google seems to like to shake things up a bit and add some new criteria by which they rank sites. One of the most recent of these shakeups was that your site might now be ranked based on whether it supports https. This led to a massive freak out in which everyone and their mom tried to set up HTTPS on their site. Historically, getting HTTPS working isn’t as easy as all that and I’m sure many of you reading this post were either too intimidated by the process or started and then gave up.
Recently I got HTTPS working on my site(s), and I’m going to share with you how I got it working (for free).
What is HTTPS?
HTTPS is, simply, a secure layer on the HTTP protocol we use to access websites. The ‘S’ stands for secure and indicates that all your information to and from this site will be encrypted. Occasionally you’ll see this: which means that some content linked or referenced on the page was not loaded securely. This is usually the bane of a webmaster’s existence when trying to set up HTTPS on a site. While it’s not inherently bad to serve content that’s not secure, in order for your site to get the happy little green padlock, everything needs to be passed securely — including content you’re linking in from outside of your site.
Why should I care about HTTPS?
Besides the Google rankings, why should you care about securing your site? First of all, as of Google Chrome 68 (coming July 2018) all websites are REQUIRED to use HTTPS.
If you’re running eCommerce on your site, you have to for secure payments. Maybe you can work around this by using a service or platform that takes the transaction part of the shopping experience off your site (like PayPal), but that can be jarring to the user experience. It also inspires trust in your customers to see a green padlock on your site; they know that they can trust you with their business even if you are sending them off to a third party for the transaction and aren’t storing any personal information locally.
But even if you aren’t selling things on your site you should still care about making your site secure. It was recently discovered that the NSA stores huge amounts of data collected from the normal internet usage of people like you and me. Unencrypted sites means that it’s easy for them to get this data, and any additional information/data sent to or from that unencrypted site. While encrypting your site might not be a foolproof way to prevent the NSA from spying on you, it wouldn’t hurt, and it can at least make it more difficult for them to access your data.
Okay, what do I need to do?
SSL certificates range in cost from $5 to $500 depending on where you get them and what they do. I’m not an expert, so I couldn’t even tell you the difference. In a lot of cases you can just contact your host for a security certificate and let them set it up for you, then change your URLs in WordPress.
But that’s not what I did.
A while ago (in fact, not long after Google’s announcement), Cloudflare announced that they’d be offering free SSL to all Cloudflare users, including those (like me) on their free plans. For those of you not familiar with Cloudflare‘s service: they are a DNS service that, among other things, allows you to manage all your domains through their nameservers. In addition to that, they add some additional security and speed-boosting enhancements like caching when you are using their service.
Instead of getting a whitescreen if your server goes down, your users will get either get a message at the top of the page saying that they are looking at a cached version of the page or a Cloudflare error page that says there’s a problem connecting to the server and no cached version of the page could be found (it’s a bit nicer for your users than an Internal Server Error message on a white page). I’ve loved Cloudflare’s free service for years because I like being able to manage all my domains in one place. Having a third-party service managing my nameservers means, too, that if I switch webhosts, I only have one place to make the adjustment to the nameservers (rather than having to go into different domain registrars to change each one individually).
Since I was already using Cloudflare, using Cloudflare’s Universal SSL was a no-brainer and, in fact, when I tested it out on a whim one day–just by putting an https in front of my domain name–I was shocked to see that it actually worked!
Okay, it didn’t really work. There were parts of the page that were broken and not displaying correctly, but the fact that it displayed anything at all, instead of just an error message saying a secure connection could not be made, gave me hope and sent me on the path to set up SSL on my (multi)site.
(Note: Cloudflare’s SSL free certificates have multiple domains on them, so it’s possible that some of those might not be sites you want your site to associate with, especially if you’re doing this for a business or corporate site. This tutorial is assuming you’re like me, and just want to set this up for personal use. Cloudflare is active on Twitter and you can always contact their support staff if you have specific questions or issues.)
For this particular recipe, you will need the following ingredients:
- An account on Cloudflare. Go get one for free if you don’t have one already.
- A WordPress-powered site. I’ll be using my Multisite as an example.
- (Possibly optional) WordPress HTTPS – a plugin that forces HTTPS links across your site(s).
- (Possibly optional if you want mapped domains) WordPress MU Domain Mapping – This is used to easily map custom domains to specific sites on your Multisite.
I’ll assume you have the first two things–a Cloudflare account and a WordPress install. If you have both those things set up and you just throw an https in front of your domain, you’ll probably get something that looks horrible like this:
This is because, as I mentioned before, there are unencrypted elements on the page. There are iFrames serving unencrypted video files and there’s Stylesheets and Javascript serving from http instead of https. All of these things can lead to something that makes you want to cry and claw your eyes out.
This is where WordPress HTTPS comes in. Basically, what WordPress HTTPS does for you is force it so that anywhere on a page where there is an “http://” it’s replaced by an “https://”. Every javascript, every stylesheet, every link, every everything. This is a lot easier to manage than trying to track down every individual unencrypted element on your page and fixing it individually (which I did see suggested when I was working on this).
On Multisite, you can Network Activate WordPress HTTPS and you’ll get a screen like this in your Network Admin:
Here I’ve got all the sites on my network listed, along with their SSL hosts (in this case, all my certificates are “self-hosting,” meaning the host is just your regular, root domain), and a couple checkboxes for some global settings.
Specifically, I’m forcing SSL in the admin (this takes the place of the define( 'FORCE_SSL_ADMIN', true )
that you can define in your wp-config.php file–read more about it in the Codex), and I’m removing unsecure elements from the page. This prevents insecure elements from giving you a broken page or a non-green padlock; anything it can’t explicitly fix, it’ll just drop so you can deal with it later and, in the meantime, get your 100% secure site up and running quickly.
If there are some sites on your Multisite that you don’t care or want to be on HTTPS, you can just force SSL in the admin or just leave those unchecked.
In each site’s admin, I have some additional, granular controls over how HTTPS is handled for that site:
You can see here that those same settings from the Network Admin screen, Force SSL Admin and Remove Unsecure Elements, are repeated, and from here, you can override them if you want. It also automatically maps ShareThis and Gravatar URLs to their secure counterparts, and you can use those as boilerplates for mapping your own domains if and when you come across elements that aren’t secure (but could be at a different/altered URL as opposed to just an https:// version of the existing URL). If you really want to get fancy, you can create filters so that certain parts of your site are secured, but other parts are not.
For me, I wanted the whole site to be secure, and these days, there’s no real reason to not just secure everything (especially if you are doing it for Google rankings or because you’re concerned about privacy).
Now, there’s one other part of this and that’s the Domain Mapping component. Otto has an excellent post on WordPress MU Domain Mapping, and covers it far better than I could. If you’re mapping custom domains to your WordPress Multisite, I recommend checking out his post first. The post is a little old but not much has changed since it was written.
Domain Mapping makes it so that on my Multisite, I can edit the full URL of the domain and map it to a specific site ID. I can do this from the normal Multisite Edit Site screen but I also need to do this from the Domain Mapping Domains page. However, if you’re using Domain Mapping, you still can’t edit the http/https part of the URL.
This needs to be done in the Site Settings tab:
That works fine for my subsites, but those fields aren’t editable for my main site.
In this case, you have a couple options:
1) Don’t do SSL on your main site, or just force it on the admin (this might still give you some headaches as WordPress will still be looking for http paths for elements in the admin).
2) Don’t setup Multisite until after you set up your SSL (probably ideal, but not always possible).
3) (╯°□°)╯︵ ┻━┻ give up
4) Hack your database.
As scary as the last option sounds, and as easy as it might be to break stuff, that’s what I’m gonna suggest. As long as you go into it with an understanding that stuff could break and a backup plan if it does (go back and fix things in the DB that you changed or restore a backup), it shouldn’t be that scary.
To do this, first, BACK UP YOUR DATABASE.
Seriously, back it up. In fact, back it up now, while you’re thinking about it.
Now, you’ll need access to phpMyAdmin from your host or the Adminer plugin for WordPress. If you’re more familiar with hacking the WordPress database (like I was), you might know what’s coming already: in your wp_options table, you’re looking for the siteurl and home options. Both of those will have http:// addresses and you just need to change the http to https. Then, go into the wp_sitemeta table and change the siteurl to https there. Again, MAKE SURE YOU BACKUP YOUR DATABASE BEFORE YOU DO THIS! If you used the Adminer plugin to edit your database, delete it once you’re done. There’s no reason to keep it around but there are many reasons to get rid of it.
If everything went smoothly, your Multisite should be all https-ified and you should be looking at a shiny green padlock. Now, if that padlock still isn’t green, you’ll want to open up Google’s Developer Tools (or Safari’s, or Firefox’s) and try to identify what elements on the page aren’t being delivered securely and address those individually.
One thing to note with the domain mapping plugin. They upgraded it and the upgraded version works completely differently than the previous version and in the case of the multisite I run, broke things. The users want to use one URL to administer the multisite (all sites) and use other URLs to access the front-end of the sites. The new domain mapping forces users to use the front-end URL for editing unless the user is in the network administration area, and there it will use the original URL. Not good to change functionality like that.
Other than that, thank you for this lovely information. 🙂
I was using the version on WordPress.org here: https://wordpress.org/plugins/wordpress-mu-domain-mapping/
There have been no updates to that plugin for some time. WPMU DEV has a similar plugin that I believe started off as a fork of this one but is a different plugin and maintained by WPMU DEV. I don’t have any experience with that plugin.
Good writeup, Chris.
You should add a 301 redirect from http to https, and add an HSTS header. This will ensure users are always sent to your https site.
Also, you should be aware that Cloudflare’s Flexible SSL presents a violation of the principle of an HTTPS connection, and is a breach of trust. The connection from the client to CloudFlare is secure, but the connection from CloudFlare to the customer’s web server is plain HTTP. It’s better than nothing, but if you’re sending or receiving any data that is sensitive, you shouldn’t use Flexible SSL.
Great points, John. Thanks! 🙂 Definitely need to add a redirect, was just thinking about that the other day.
Hey Chris
Thanks a lot for that tutorial. It saved my day and a lot of hours.
– Dominic
w00t! Glad it helped!
Thanks for the great write-up! Your ssl cert ist broken btw. Cheers
Thanks for the tutorial!
THE HTTPS WordPress plugin is discontinued.
I used the define (‘FORCE_SSL_ADMIN’, true).
My SSL is only for main site. When do I enable define (‘FORCE_SSL_ADMIN’, true) can not seem to access the administration area of the other sites in my network. How do I force HTTPS only in the area of administration of the main site?
Thanks in advance.
att,
Josimar
(Brazil)
I don’t see any indication on the plugin’s home page (http://mvied.com/projects/wordpress-https/) or on the GitHub repository (https://github.com/Mvied/wordpress-https) that development has stopped on the HTTPS plugin. When I search in the WordPress.org repository it comes up, albeit with a flag that it hasn’t been updated recently: https://wordpress.org/plugins/wordpress-https/ but the version in the GitHub repository was updated 28 days ago (as of this writing).
FORCE_SSL_ADMIN will only secure the /wp-admin/ of a site, not put the whole site (and sub-sites on multisite) under HTTPS. You’re probably not able to access the admin either because you’re trying to access the site at a URL it doesn’t recognize (the sites are still configured at http://domain.com instead of https://domain.com) or you don’t have an SSL certificate for those domains. I would recommend just using the plugin.
Great article. Any advice on best setup for developing locally and pushing to production? I was forcing https locally and then accepting the warning, but now unable to to upgrade network to WP 4.4 so considering running the local without and the production with.. Any feedback appreciated.
I never had that issue when I’ve had situations where I was forcing https locally and the live site was using SSL, but then it could depend on how you’ve set up your local/production environments. The way we set up our projects, the wp-content directory is the git repo, so WordPress updates are not managed by version control. While you could run local without and production with, I’d avoid that if possible because of the mismatch leading to possibly introducing errors/problems/inconsistencies. That said, your mileage may vary and it depends on how you have your environments set up.
Two things. First, the following two statements in your .htaccess file will force SSL for all your sites:
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
Secondly, on John Blackbourne’s point, you can use a self-signed certificate to encrypt the data between CF and your site. CloudFlare doesn’t care. And your traffic will be fully encrypted.
Now, one question. I’ve updated both wp_options and wp_sitemeta. I even used an editor to changed all “http://my.site” to “https://my.site”. The page …/network/site-settings.php?id=1 shows both URLs with https://… but /network/site-info.php?id=1 shows the site as http://… (no “S”). Where the heck is that setting? I can’t find it in the database or wp-config.php.
TBH I don’t know specifically where in the database that value is pulled. I’m guessing it’s a multisite-specific option since the data on your site settings page is pulled from that site’s wp_options table (e.g. wp_2_options). For sites that aren’t your main site you can manually just edit that value, but for your main site, you can’t. It could just be defaulting to display http instead of https, because the values I pulled in my database in wp_blogs and wp_site are just the domain (e.g. jazzsequence.com) without any http/https. That said, it shows up on that page as https for me, so it might also have to do with using the WP HTTPS plugin.
¯_(ツ)_/¯
If it’s not causing any actual issues with HTTPS (you can log in at https and you don’t have any insecure content warnings), I wouldn’t stress too much over it.
Worked like a charm to get the https working on my main domain and all its subdomains, but it also made it unable for me to login to my website by using wp-admin nor wp-login.php; it shows this message in the browser: ERR_TOO_MANY_REDIRECTS
Any suggestions on how to fix this? Thanks in advance
Sounds like you’ve still got http urls in your settings somewhere. What it sounds like is happening is you’re trying to access wp-admin with https, but the setting is http so it redirects you there, but you’re forcing https, so it redirects you again. If you can hit wp-admin at http to log in, try that (I can log into my site at either http or https), if not, check your database. (Hint: first place I’d look is wp_options for siteurl and home.)
hey, i am having a hard time implementing this tutorial on my multisite.My multisite is based on subdirectories.A quick question what did you wrote in servers ip in plugin settings , cloudflares server ip adress or hosting provider server ip adress. I wrote cloudflares ip adress and im unable to collect the things up . Any help pls.
Hi Hitesh —
For the domain mapping settings I am using the hosting provider server IP address. Cloudflare comes in after the fact.
Hey Chris,
I have set up a multisite and tried to turn on ssl how you described above. When I do the admin panel uses ssl but the front end refuses. It redirects if i try to type in https.
Ugh – I’m having a problem with this right now. My host offers both a free wildcard ssl as well as Let’s Encrypt but it seems like I really need both.
Using the wildcard, the subdomains for the network sites (site1.mymultisite.com, site2.mymultisite.com, etc.) are covered but not the parked domains.
Using Let’s Encrypt, all of the parked domains are covered by SSL but NOT the network subdomains – in which case all the images, files, etc are broken as the site as using WordPress HTTPS to force it is not working.
Maybe I’m getting something wrong? I’m at the point of thinking that a multisite just isn’t worth the hassle and I need to migrate the important sites that need to be secure off multisite somehow.
I am using a subfolder maintenance of multiple sites on the same domain, and I am having problems with images pointing to the wrong directory with https but not with http.
Let me explain with an example.
The file is located (FTP) at http\wp-content\themes\theme1\images\image1.jpg
The link to (non-SSL) http://www.example.com/site1/wp-content/themes/theme1/images/image1.jpg would display the image, however, the link to (SSL) https://www.example.com/site1/wp-content/themes/theme1/images/image1.jpg would NOT display the image.
However, after investigating further, this (SSL) link would display the image https://www.example.com/wp-content/themes/theme1/images/image1.jpg , i.e. “site1” is removed from the URL.
Is there a magical .htaccess RewriteRule that would fix my problem?
I managed to fix the error. If you are using subfolder sites (instead of subdomains), you may wish use the following settings:
My Sites > Network Admin > Sites > Edit (the site) > Settings
Now, set Siteurl to https://www.example.com (instead of “https://www.example.com/site1”) and set Home to https://www.example.com/site1
Hi,
Thank you so much to write a great post
I have done according your description and my site https://www.cyberpratibha.com is running on https, I have multisite based on subdirectory and https://www.cyberpratibha.com/blog is running on https but image are nor displaying on my blog,
Any suggestion
Thanks and Regards!
Vijay Kumar
Mr. Jeffrey….. Do you know if Force SSL one can working in Multi WP?? https://wordpress.org/plugins/force-https-littlebizzy/
I have the opposite problem than a lot of people. I have had no problem getting the SSL to work on my main domain but I cannot get it to work on the subdomains. I followed the instructions above exactly so I am not sure why. I followed all of the steps, then undid everything after the subdomains would not load, redid it, and I keep running into the same issue. It’s possible that I am not waiting long enough for it to resolve but I don’t think that is it. I did sleep on it before trying again but same results, 9 hours after the first attempt. When I try to visit the dash of a subsite it forwards to https but I get a 404 error from my hosting provider saying the page doesn’t exist. I am thinking I must’ve missed something, unless this is just an old thread and no longer relavent, but I don’t think that is it.
Here is what I did:
1. Set up cloudflare
2. Changed domain name servers
3.Installed and network activated WordPress HTTPS
4. Configured Plugin as described above
5. Changed URL’s to https in the database where required and also edited the subsites to https via network admin.
6. Changed settings in Cloudflare to Flexible SSL, set always use SSL and auto HTTPS Redirects to on.
It’s not working for me. When I load a subsite I get the error. If I delete the S at the end of https and the 404 error in the address bar, the page will load; same with admin for the subsite.
It’s just the subsites that are not https, the main domain is. Any help is much appreciated. Thanks!
Hello, thanks for the comment and I’m sorry to hear you’re having trouble setting up HTTPS. A few things to check for troubleshooting
– If you can reach the subsite’s Dashboard, make sure to go to the Permalinks settings (Settings->Permalinks). Visiting this page will flush WordPress’s internal permalinks and can often be a cause of 404 issues.
– Is your Apache or Nginx server properly setup to serve over HTTPS? See https://stackoverflow.com/questions/11253185/404-error-with-wordpress-ssl?rq=1
– Is there possibly a directive in your .htaccess that is routing SSL traffic to the wrong place?
– You can verify that your subsites have the proper URLs set by going to your database and finding the site options tables. For a site with ID “2”, that table would be “wp_2_options”, for example. Ensure that both the “siteurl” and “home” options have “https://” URLs.
I hope this helps. Please let me know if you need more guidance, and good luck!