Switching Sites from HTTP to HTTPS

Best-practice HTTPS configurations for WordPress and Drupal to fix mixed-content browser warnings and excessive redirects.

Tweet

All new sites created on Pantheon are configured for HTTPS by default. HTTPS is available immediately for Platform domains like multidev-example.pantheonsite.io.

When you upgrade to a paid plan you can connect a custom domain. For more information on HTTPS provisioning for custom domains see HTTPS on Pantheon's Global CDN.

The following describes how to switch WordPress and Drupal sites over from HTTP to HTTPS.

Before You Begin

Be sure that you have:

  • A Paid Pantheon plan

  • A Custom Domain connected to the target Pantheon environment (typically Live), set to the primary domain, with DNS properly configured.

  • HTTPS provisioned, indicated by the following notice:

     HTTPS

    Let’s Encrypt certificate deployed to Pantheon’s Global CDN. Certificate renews automatically with no additional cost.

Test HTTPS Availability and Existing Redirects

Start by testing a simple HTML or Text file in your browser with HTTPS on your custom domain. The test is successful if the browser loads the file securely with no warnings:

Example HTTPS Test

Requests bounced from HTTPS to HTTP indicate test failure. Remove existing redirects to HTTP within the site's framework (e.g., wp-config.php or settings.php) in addition to CDN configurations if applicable (e.g., page rules in Cloudflare).

Mixed-content warnings in the browser are expected at this stage; such issues will be visible in Chrome as an HTTPS URL with either no “Secure” label or a “Secure” label and a small warning icon:

Mixed content browser warnings

Continue once you're able to load a normal page of your WordPress or Drupal site with HTTPS without redirecting (browser warnings are okay for now).

Assume HTTPS Within WordPress and Drupal

Configure your site to assume users are visiting via HTTPS and the site’s primary domain. Templates for example should reference HTTPS in absolute CSS and Javascript sources, even when accessed with HTTP. While testing, you may find it necessary to bust through the edge cache by adding something like ?cache-bust=1 to the end of a URL.

Reveal Violations in bulk

There are more than a few ways to identify mixed-content violations across your site, but Google Chrome is arguably one of the fastest and simplest. Right click on a page showing as insecure and select inspect, then review the console.

Another easy to use tool is https://www.whynopadlock.com/, for those who prefer GUIs.

Fans of the command line might find mixed-content-scan by Bramus helpful.

Hotfix Violations in bulk

If you're in a bind and need a quick fix, set the Content-Security-Policy header to upgrade-insecure-requests to upgrade all HTTP resources to the HTTPS protocol client-side, on the fly:

// Upgrade HTTP requests to secure HTTPS
header("Content-Security-Policy: upgrade-insecure-requests;");
// Report all insecure requests, but do not refuse
header("Content-Security-Policy-Report-Only: img-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline';");

Use this as temporary solution while working to fix each problem at its origin.

Database Cleanup

Use the following techniques to replace insecure references to your domain in the site's database. The result should be that the browser loads pages of your WordPress or Drupal site securely with no warnings.

Via Plugin

You can use the Really Simple SSL plugin to automatically detect and fix mixed content messages. For additional details, see this related blog post.

Via WP-CLI

If you'd rather not add another plugin to the site you can use Terminus to run wp search-replace to converts URLs from HTTP to HTTPS:

terminus remote:wp <site>.<env> -- search-replace 'http://www.example.com' 'https://www.example.com' --all-tables --verbose

Via Site Dashboard

If you don't have Terminus installed, or are unfamiliar with working in the command line, WordPress sites have the option to replace the URLs from the Pantheon Dashboard.

 Warning

This will not work for Multisite installations, and can result in data loss on sites with active transactions, as well as other non-standard configurations.

  1. From the Test environment, clone your database from Live:

    Cloning the Live Database to Test

     Warning

    Be sure that you are cloning in the right direction. If you accidentally replace your Live environment's database, you can lose data.

  2. Now, from the Live environment, clone your database back from Test, making sure to select "https" under Convert URLs' Protocol to::

    Cloning the Test database to Live, while converting URLs

Drupal 7 sites can use Drush Search and Replace (sar) by adding custom Drush command.

Drupal 8 sites can use the Entity API to fetch data from entities in the database that may include insecure references.

Clear Caches

Clear Drupal and WordPress object caches in the database and/or in Redis in addition to manually flush edge caches by going to your Pantheon Dashboard and clicking the Clear Caches button.

At this point, all visitors to the site should be able to securely access all pages over HTTPS with no browser warnings.

Redirect to HTTPS and the primary domain

The best way to redirect to HTTPS is via the HSTS header. Pantheon lets you configure this header in the pantheon.yml file.

 Note

Before adjusting enforce_https, review and understand the configuration options and all considerations to avoid unintended consequences.

If you use a plugin or module to set your HSTS header, it will create a duplicate header. Disable enforce_https in pantheon.yml to avoid an invalid policy.

Use of the HSTS header is defined by the enforce_https directive, and takes five possible values which are handled by Pantheon as shown below:

enforce_https:RedirectHSTSStrict-Transport-SecurityincludeSubdomainspreload
offDisabledNot set by Pantheon
transitional (default)Enforcedmax-age=300
transitional+subdomainsEnforcedmax-age=300
full Enforcedmax-age=31622400
full+subdomains Enforcedmax-age=31622400

For example, to set enforce_https as off:

enforce_https: off

Considerations

  • Use of full or full+subdomains should be treated as a commitment. HSTS headers are cached by browsers for the duration of the max-age period. If your site is unable to serve HTTPS (e.g. by moving to a host that doesn't support HTTPS), visitors will be unable to access your site.
  • Any option with +subdomains should only be used if you want to enforce HTTPS for all subdomains, even those not connected to Pantheon.
  • To prepare your site to serve all content via HTTPS, follow the Switching Sites from HTTP to HTTPS doc.

Set a Primary Domain via the Dashboard

 Warning

With a Primary Domain set at the platform level, all other domains will be pointed to your Primary domain at the root level. If you want to redirect secondary domains to specific pages on your site (for example, olddomain.com to newdomain.com/old-landing-page), do not set a Primary Domain. Instead use PHP redirects.

  1. From the environment you want to set a primary domain for (typically Test or Live), navigate to Domains / HTTPS.

  2. Ensure that all domains have been added and are listed.

  3. In the Choose Primary Domain section, select the domain to which traffic should be redirected, and click Save Configuration.

Set a Primary Domain with Terminus

  1. Install or upgrade to the latest version of Terminus.

  2. Use Terminus to add the primary domain. In this example, replace:

    • my-site with your site name,
    • live if you'd like to set it for a different environment
    • www.example.com with your primary domain:
    terminus domain:primary:add my-site.live www.example.com

Update or Remove Primary Domain

Update the Primary Domain using either method provided in the previous section.

Remove an existing selection for the Primary Domain on any environment using Terminus:

terminus domain:primary:remove my-site.live

Replace my-site with your site name, and live with the environment you're removing a primary domain from.

Verify

You can confirm that the Primary Domain has been removed with cURL pointed at one of your other custom domains, which would previously have been redirected:

curl -I https://example.com
HTTP/2 301
retry-after: 0
server: Pantheon
location: https://www.example.com/
x-pantheon-redirect: primary-domain-policy-docdate: Wed, 05 Feb 2020 16:43:21 GMT
x-served-by: cache-mdw17355-MDW
x-cache: HIT
x-cache-hits: 0
x-timer: S1580921002.586800,VS0,VE1
age: 0
accept-ranges: bytes
via: 1.1 varnish
content-length: 0

The presence of x-pantheon-redirect: primary-domain-policy-doc indicates that the domain is still being pointed at the former Primary Domain. Contact support if this value persists.

It's a best practice for SEO and security to standardize all traffic on HTTPS and choose a primary domain. Configure redirects to the primary domain with HTTPS in pantheon.yml

If your site configuration prevents you from setting the primary domain from the platform level, you can use PHP redirects:

Attempting to visit any page with HTTP or a non-primary domain should redirect to a page with the primary domain and a “Secure” label. For additional redirect scenarios, see Domains and Redirects.

Spot-check new and existing redirects

Consider your site's existing redirect logic and minimize the number of redirects whenever possible.

The bare domain should resolve to the preferred URL in a single redirect, like this:

Not like this:

cURL the bare domain with HTTP and review the output, checking for a single redirect like:

curl -LI http://example.com/
HTTP/1.1 301 Moved Permanently
Content-Type: text/html; charset=UTF-8
Location: https://www.example.com/

You can use this redirect mapper by Patrick Sexton to investigate redirect behaviors as an alternative to cURL:

Varvy Redirects example.com

Check all configured services when looking for redirects to remove, like page rules on some external CDN.