Forcing SSL Protocol for Multisite Subdomain Child Sites + cPanel Configuration

I’m running a WP multisite using subdomains. I would like to force SSL protocol for all requests and am running into an issue for non-SSL requests on my child sites. I’m using the WP Force SSL plugin. I’ve done a bit of digging around and tried the following .htaccess directive, but it doesn’t work (nor do anything):

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

For example:

  • http://derpsite.tld = redirects to SSL Protocol
  • https://derpsite.tld = works
  • http://child1.derpsite.tld = breaks. Specifically, I get a http://child1.derpsite.tld/cgi-sys/defaultwebpage.cgi cPanel error page
  • https://child1.derpsite.tld = works

EDIT 1

I’ve reached out to both my host (dedicated server that has cPanel installed) and cPanel (the latter with whom I still have an open ticket). cPanel has mentioned:

Apache on cPanel is configured a bit different than other servers you may be used to. By default, Apache will accept any domain name being requested because it’s set up as a wildcard. On cPanel servers, the virtualhosts are configured specifically for the domains you create. For example, when you created the cPanel account for defectslawyer.com, it set up a configuration that is specific to defectslawyer.com. Let’s say I point the DNS for my domain thisisarealdomain.com to your server. When I make the request for thisisarealdomain.com, Apache checks it’s configuration for that domain, doesn’t find it, then returns the cPanel default page.

It sounds like you have DNS configured correctly, I’m assuming a wildcard subdomain record pointing to your server, but Apache doesn’t know what to do with what’s being requested. At least on the non-SSL side of things. What should solve the problem is to add a wildcard subdomain in cPanel [ https://documentation.cpanel.net/display/ALD/Subdomains ] so that the Apache vhost for *.derpsite.tld is added. Then, when anything.derpsite.tld is requested, Apache will be able to find that vhost and know what to load.

The reason SSL version may be working is you likely installed the SSL as *.derpsite.tld which creates that SSL vhost.

Based on this input I have:

  • Added a wildcard subdomain within cPanel (and have the subdomain document root point to the main site root)…which now kicks out a 500 internal server error for both http://child1.derpsite.tld and https://child1.derpsite.tld)
  • I’m currently reviewing how I have my SSL set up

EDIT 2

The 500 internal server error above seems to have been the result of installing my SSL on a wildcard domain; please see my ‘answer’ below

Solutions Collecting From Web of "Forcing SSL Protocol for Multisite Subdomain Child Sites + cPanel Configuration"

From the description of the error you get, it seems like you do not get at all to your account related software when trying to access the child on http. This sounds like a web server configuration error, so in your case you need to make sure that in your cpanel you enabled subdomains for http and not only https

Thanks to everyone who commented on this, it definitely helped steer me towards the right direction and, finally, I believe that I know what happened, which was a combination of several factors. I realize that this may not be ‘strictly WP related’, but for those using cPanel, the following should be of some assistance. I’ve compiled a few ‘rule of thumb’ items that, when all in place together, seem to have resolved the issue of forcing SSL protocols:

  • siteurl and home fields in the options database table for each site (or in wp-admin … ~/wp-admin/network/sites.php > Edit Site > Site Address (URL) for each site) need to use https:// in the URL
  • If using a wildcard SSL (which I imagine will be the case for most wanting to use SSL on a subdomain-driven multisite) is installed for the root domain, not a wildcard domain. I had my SSL installed on *derpsite.tld and removed/reinstalled it for derpsite.tld
  • In DNS an ‘A’ wildcard record needs to point to the server IP, i.e. *.derpsite.tld -> YOURSERVERIP
  • In cPanel, a wildcard subdomain (*.derpsite.tld) needs to be created and the subdomain directory should be the root directory (in most cPanel cases, this will be /public_html …because, if running a multisite, you don’t actually want real directories to be created for ‘child site’ subdomains)
  • Additional note: if you are doing domain mapping, you will likely have to ‘park’ your external domain via WHM or cPanel to get it to run forced through SSL. Also, as of 4.5+ domain mapping is native). Please note: at the time of writing I am using WP v.4.8.2 and cPanel v.66.0.23 …sites running a WP version prior to 4.5 may require a different configuration
  • I’m not entirely sure if this is necessary, but I have the following directives in my root .htacess file:


RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} ^my\-mapped\-external\-domain\.tld[NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://my-mapped-external-domain.tld/$1 [R,L]

Hope this helps someone!

Because this is classed as 2 different domains, it will need to be done in 2 parts. Try this:

RewriteEngine On 
RewriteCond %{HTTP_HOST} ^derpsite\.tld [NC]
RewriteCond %{SERVER_PORT} 80 
RewriteRule ^(.*)$ https://derpsite.tld/$1 [R,L]

RewriteCond %{HTTP_HOST} ^child1\.derpsite\.tld [NC]
RewriteCond %{SERVER_PORT} 80 
RewriteRule ^(.*)$ https://child1.derpsite.tld/$1 [R,L]

You typically do not need to run plugins to force the SSL if you configured websever well.

You just need Settings -> General and change both URLs to have https:// rather than http://. Also purge the caching plugins is always the good idea. As I see the SSL certificates are in place and are working for you based on what you said.

The core of this plugin you mentioned is this:

// "The Core"
define('FORCE_SSL' , true);

if (defined('FORCE_SSL'))
  add_action('template_redirect', 'force_ssl');

function force_ssl(){

if ( FORCE_SSL && !is_ssl () )
 {
  wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], 301 );
  exit();
 }
}

As you can see PHP or WordPress has been used to force the redirection. Instead these re-directions are better and smarter on webserver level. No PHP need to be used.