Load Balancer and Bitnami application instance SSL

Keywords: WordPress - Google Cloud Platform - Technical issue - Secure Connections (SSL/HTTPS)

bndiagnostic ID: 34cda628-54de-d35a-ac00-3e2105fd9703

bndiagnostic output:

? Resources: Found possible issues
? Apache: Found possible issues
https://docs.bitnami.com/installer/faq/linux-faq/administration/increase-memory-linux/
https://docs.bitnami.com/general/apps/wordpress/troubleshooting/debug-errors-apache/
https://docs.bitnami.com/bch/apps/moodle/troubleshooting/deny-connections-bots-apache/

bndiagnostic failure reason: The suggested guides are not related with my issue

Description:
The Wordpress website has been running on a VM Instance (Google Cloud) for some time without a Load Balancer. When the site was initially setup on the VM instance, SSL was configured using the auto configured Lets Encrypt Certificate.

Now we have setup a load balancer using the Google Cloud and are getting “err too many redirects” when we point the domain A Record to the Load Balancer.

I’ve tried to use the Load Balancer instructions for Google Cloud (following the steps here - which are for multi-tier, and somewhat out of date):
/how-to/configure-lb-ssl-google-templates/

At Step 8: For a single Wordpress site installation, which files should be modified in the application instance to configure the HTTP redirection?

The files “wordpress-vhost.conf”, “bitnami.conf”, “bitnami-ssl.conf” , for example, all include a series of http and https rewrite conditions and rewrite rules in the <VirtualHost… block.

We can see that there is a line to set environment already present by default in
opt/bitnami/apache/conf/bitnami/bitnami.conf at the top of the file. Where this line is already present by default:
SetEnvIf x-forwarded-proto https HTTPS=on

Can you please specify what new lines are to be added and if they are to replace or added beneath or above the existing conditions and rules? I am very confused about which files to edit and where, as far as it relates to the edits to the rewrite rules.

When the Load Balancer has a Google Managed Certificate, what should be done with the Lets Encrypt Certificate that was already installed on the installation? Should the certificate be removed on the installation? If so, how is this done? With the bnn-cert tool?

In the wp-config file I have modified the WP_SITEURL and WP_HOME (below). Is this correct for the load balancer settings or should this be restored to the default?

define( ‘WP_HOME’, ‘https://www.MYDOMAIN.ca’ );
define( ‘WP_SITEURL’, ‘https://www.MYDOMAIN.ca’ );

*in my wp-config file I modified the http to https and included my actual domain name.

Should the following line also be added to wp-config, beneath the lines above (as mentioned in the instructions for the AWS installs)?:

if (strpos($_SERVER[‘HTTP_X_FORWARDED_PROTO’], ‘https’) !== false)
$_SERVER[‘HTTPS’]=‘on’;

Thank you!

Please note that if the load balancer is using http when connecting to the instance, if you have any action in the wordpress-vhost.conf or wordpress-https-vhost.conf files that redirects to https, it will generate this redirection loop. Could you please review that?

Please note that there are 2 wordpress files inside the vhosts folder, wordpress-vhost.conf and wordpress-https-vhost.conf.

Thank you for the reply.

The file “wordpress-vhost.conf” and the file “wordpress-https-vhost.conf” are both present (see code from each file below).

  • The file “wordpress-vhost.conf” includes a rewrite condition and rule for HTTP to HTTPS. Should this be removed?

  • Should the lines from Step 8 in “/how-to/configure-lb-ssl-google-templates” be added:

Edit the /opt/bitnami/apache/conf/vhosts/wordpress-vhost.conf file and add the following lines below the RewriteEngine On line:

  RewriteCond %{HTTP:X-Forwarded-Proto} =http
  RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]

In wordpress-vhost.conf we see:

# BEGIN: Enable HTTP to HTTPS redirection
  RewriteEngine On
  RewriteCond %{HTTPS} !=on
  RewriteCond %{HTTP_HOST} !^localhost
  RewriteCond %{HTTP_HOST} !^[0-9]+.[0-9]+.[0-9]+.[0-9]+(:[0-9]+)?$
  RewriteCond %{REQUEST_URI} !^/\.well-known
  RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [R,L]
  # END: Enable HTTP to HTTPS redirection
  # BEGIN: Enable non-www to www redirection
  RewriteCond %{HTTP_HOST} !^www\. [NC]
  RewriteCond %{HTTP_HOST} !^localhost
  RewriteCond %{HTTP_HOST} !^[0-9]+.[0-9]+.[0-9]+.[0-9]+(:[0-9]+)?$
  RewriteCond %{REQUEST_URI} !^/\.well-known
  RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=permanent,L]
  # END: Enable non-www to www redirection

In wordpress-https-vhost.conf we see:

  # BEGIN: Enable non-www to www redirection
  RewriteEngine On
  RewriteCond %{HTTP_HOST} !^www\. [NC]
  RewriteCond %{HTTP_HOST} !^localhost
  RewriteCond %{HTTP_HOST} !^[0-9]+.[0-9]+.[0-9]+.[0-9]+(:[0-9]+)?$
  RewriteCond %{REQUEST_URI} !^/\.well-known
  RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=permanent,L]
  # END: Enable non-www to www redirection

Finally, LetsEncrypt certificate was installed on this installation. The load balancer has a Google managed certificate (i.e. one certificate installed on the Load Balancer and one certificate installed on the actual application web server). Is this OK?

Thank you again.

Please note, bitnami.conf and bitnami-ssl.conf also contain the same RewriteEngine actions. Do we also need to change the RewriteEngine actions on these files?

Hi @aaron2022 ,

I asked you to review that but after checking the code, it’s redirecting if the request doesn’t use localhost or an IP. I understand the load balancer is using the IP to connect to the instance, right?

Please add them.

No, because the wordpress-* files rewrite that configuration.

Final suggestion: I can see it’s WordPress who is redirecting to https and that’s because WordPress has the WP_HOME and WP_SITEURL parameters set to https://www.domain.ca. You can change it to use the host of the request so you do not get redirected

define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST']);
define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST']);

Hello - Thank you for the responses Jota - I will test these out and report back on this thread.

Hi @jota I have this working now.

I would like to share the notes about how I did it. There are some key steps at GCP tl;dr

  • the health check needs to use TCP, not HTTP,
  • and I’ve tagged the VM and created a firewall rule to allow the health check.
  • The application configuration seems to be OK with edits made only to “wordpress-vhost” file.

Current results are providing the redirect when browsing normally to “domain.com” with ‘www’ or without, and also upgrading requests to force browsers using the VM Instance IP address and also the Load Balancers IP address to be converted to the “domain.com” properly.

Background
This site was installed using the Market Place method, on a Google Cloud Compute / GCP, Compute Engine Virtual Machine with LetsEncrypt setup (and operational for several months).

The Load Balancer has now been added with its own Certificate (from Google) and appears to be functioning normally after the domain A record was updated.

Notes

Application:
wordpress-vhost.conf modifications from Step 8 in “/how-to/configure-lb-ssl-google-templates” - link below - I have added:

RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]

Then I have commented out the lines in the block “BEGIN: Enable HTTP to HTTPS redirection” which I think will be present only if you’ve installed/configured LetsEncrypt.

Then, in the file wp-config - I have explicitly set the URLs for WP_SITEURL and WP_HOME as https and the fully qualified name with the www.

define( ‘WP_HOME’, ‘https://www.domainname.com’ );
define( ‘WP_SITEURL’, ‘https://www.domainname.com’ );

In setting up the Load Balancer, the notes in the Bitnami documentation for Google Cloud Compute (link below) are good, but out of date, with some new settings options.

Note, it seems the Health Check needs to connect to the backend using TCP (not HTTP as stated everywhere).

Note, Tagging the VM and using the tag (allow-health-check), and creating the firewall rule for this can be seen in the tutorial here: Setting up an external HTTPS load balancer  |  Identity-Aware Proxy  |  Google Cloud (Please note, this Google tutorial reference is noted for firewall only, this type of managed instance load balancer in the tutorial doesn’t work with the Bitnami app :frowning: - but the firewall rule notes are good :slight_smile:

Note, Google Certificate added to the load balancer should include www.domain.com and domain.com and any subdomains you plan to use.

Note, When setting up Load Balancer, select the new options at GCP for

  • “Global HTTP(S) Load Balancer (classic)” and select “internet to VM traffic”,
  • When your create your instance group this needs to be an Unmanaged instance group, as you will be “bringing your current instance into this new group”
  • Select options “From Internet to my VMs or serverless services”
  • Do you want to deploy your application in global, regional, or classic mode? "
    – Global HTTP(S) Load Balancer (classic)"

Docs: Configure Load Balancing with SSL for Bitnami Multi-Tier Solutions on Google Cloud Platform

Next steps, I will be testing the re-addition of my HTTP directives, CSP, no-referrer and no-sniff etc, disable old TLS versions on the Load Balancer and then move on to adding Google Cloud Armour to the Load Balancer, which was the key objective.

Hi again, just to report that this solution appears to be working properly and update on:

  • the re-addition of http headers i had temporarily disabled in the httpd.conf file are now working on the website (CSP, Strict Transport, No-sniff, Sameorigin, referrer-policy, permissions policy etc.). This is functioning behind the load balancer.
  • once the load balancer is created we can adjust the TLS settings via GCP, Network Security, SSL Policies. This is for the load balancer (not the VM where the website is installed). So even if you’ve already configured TLS settings on the website server, you’ll need rules applied on the load balancer IP to restrict older TLS 1.0 and 1. 1

Hi @aaron2022 ,

Thank you for all the information, I’m sure it’ll be really useful for all the Bitnami users :slight_smile:

I will let you know how it goes deploying the same setup to Production. All that testing work and trying to get it working was done so we can deploy on Production with almost zero downtime.
Thank you,
Aaron

Hi @jota - One last question on this thread, seems like its mostly all working.

The solution seems to be working OK on production, tl:dr;

  • The GCP load balancer settings seem to need to use TCP for the Health Check
  • Firewall rules and tagging the VM to allow the health check were added into the Load Balancer setup steps.
  • The only modifications I’ve made were to the wordpress-vhost.conf file. Keeping in mind that these sites were already running with their own letsencrypt setups.

Now we have the GCP load balancer IP address (aaa.aaa.aaa.aaa) receiving the traffic and loading the websites from their own IPs.

When a user visits http://www.domain.name or http://domain.name they are redirected to https://www.domain.name (and the site/backend is displayed properly).

When a user visits the VM Instance IP address (at http://bbb.bbb.bbb.bbb) they are redirected to https://www.domain.name (and the site/backend is displayed properly).

So far so good. :slight_smile: here is the remaining issue I’m seeing:

When (if) a user visits the front-end IP of the Load Balancer (http://aaa.aaa.aaa.aaa) - we get an error,
“NET::ERR_CERT_COMMON_NAME_INVALID” and we see that we are not redirecting or rewriting those requests to the FQDN address. We see the address remains the numerical IP and and the warning that the server at aaa.aaa.aaa.aaa cannot verify.

I am pretty sure we want anyone who requests the Load Balancer Frontend IP address to be directed to FQDN to avoid this error (note this Frontend has a static IP, and Google Cert that recognizes both www.domain.name and domain.name).

My question is - how do I rewrite those requests to the front-end IP of the Load Balancer so that:
http://aaa.aaa.aaa.aaa or https://aaa.aaa.aaa.aaa will resolve to https://www.domain.name

I am not sure where to resolve this last remaining issue. It appears that the Load Balancer host and path rules can handle this for us. Any help to close this out would be greatly appreciated.

I understand the LoadBalancer is redirecting those requests to https://aaa.aaa.aaa.aaa and the certificate you own is not valid for that IP (it’s not a valid domain either).

You will need to investigate first “who” is generating that redirection. For example, if the LoadBalancer is in charge of that, you will need to contact the Google’s support team to get the necessary info to redirect the request to the correct domain. If it’s WordPress (and if you configured the domain name in the wp-config.php file), the WordPress support team should describe how to do it. In the case of being Apache who redirects the request, you will need to update the Apache’s configuration (/opt/bitnami/apache/conf/vhosts folder) to redirect to your domain every time a requests that uses the IP is received.

Is it possible to confirm the process? As noted, we have the explicit URL in wp-config.php, we have the redirects all functioning when the name is used.

Can someone confirm how to ensure these redirects are placed correctly in these GCP deployments behind a load balancer?

Hello - the solution to ensure that redirects for requests to the domain name or the IP addresses of the LB or the primary VM are working the way I wanted, appears to be to change the settings of the http to https load balancer that is created when we create a new GCP load balancer with this option selected (HTTP to HTTPS).

I’ve edited the Host/Path settings for this second load balancer that is created automatically when creating new load balancers, (a partial load balancer which has an URL map that we can adjust, labeled “-redirect” by default). By adding the host name in the field “Host Redirect” and checking the option for Strip Query.

I had to save the setting a few times, and flush my local DNS cache to see this finally take effect, but it appears to be working properly to send only the domain name as the host for all requests to the site.

This setting required me to change the configuration in wp-config to remove the explicit URLs and instead use the default settings for WP_HOME and WP_SITEURL
Without changing this back to the default as below, we encounter an endless loop on redirects.

define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST'] . '/');
define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST'] . '/');

Additionally, the vhost edits described earlier in this thread are working ok. Here is what I have now.

  RewriteEngine On
  # BEGIN: Enable non-www to www redirection
  RewriteCond %{HTTP_HOST} !^www\. [NC]
  RewriteCond %{HTTP_HOST} !^localhost
  RewriteCond %{HTTP_HOST} !^[0-9]+.[0-9]+.[0-9]+.[0-9]+(:[0-9]+)?$
  RewriteCond %{REQUEST_URI} !^/\.well-known
  # END: Enable non-www to www redirection
  # BEGIN: manage forwarding from WAF to https
  RewriteCond %{HTTP:X-Forwarded-Proto} =http
  # END: manage forwarding from WAF to https
  RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]

I’m observing this on the test site, and will deploy to production if it all looks OK.
Hopefully it will be smooth from here.

Great to hear that you managed to solve this problem! :slight_smile:

This is necessary because if you do not do it, the load balancer will use the IP to connect to WordPress and the app will redirect you to the domain creating the loop you mentioned.

Enjoy! :slight_smile:

Hi,

Sorry to report, there is still an issue where with the configuration we are now not handling requests for the VM properly.

Requests to the VM IP address are now not being rewritten to use the domain name.

When a user visits the VM Instance IP address (at http://bbb.bbb.bbb.bbb) they now not are redirected to https://www.domain.name (and the site/backend is displayed properly). The user can browse the site, but the URLs are using the VM IP address.

How can we now ensure that browser requests to http://bbb are rewritten to the domain name?

Thank you

Final tweak, added above the final rewrite conditions and rewrite, to also handle the requests that might come to the static IP address of the VM.

The previous settings on GCP and as noted in my previous post on this thread for my configuration all seem to work to handle the redirects/rewrites when we are now behind the Load Balancer.

As as final step I’ve update the vhost.conf file to bypass the route for the IP address of the VM - substitute ‘bbb.bbb.bbb.bbb’ with the actual IP of the VM, and update the ‘www.yourdomainname.com

  # Default route to bypass VM IP
  RewriteCond %{HTTP_HOST} ^bbb.bbb.bbb.bbb$
  RewriteRule ^(.*)$ http://www.yourdomainname.com/$1 [L,R=301]
  # End Default route to bypass VM IP

This has been added after “RewriteEngine On”, and before the rewrite conditions and rule described in the previous post on this thread.

It works, although not totally ideal, as I would prefer to not have to specify these explicitly in the file “*-vhost.conf”, however, it seems this way, we can deal with bypassing the VM IP address and the Load Balancer IP (done at GCP), and both sets of rules seem to play nice.

Thanks

Hi @aaron2022,

I’m glad to hear your found a solution, thanks for sharing it.

Regards,
Michiel