0
votes

I have a fresh server configured with: varinsh on port 80 (configured to redirect direct requests to 443) nginx on port 443 (forwards to varnish) apache on 8080 (wordpress installed here)

When I load the wordpress site all the js files are trying to load on 80 and are insecure.

Wordpress is set to override WP_HOME and WP_SITEURL to https://example.com

I found an article that said I need to do this: (nginx) proxy_set_header X-Forwarded-Proto $scheme; and then in your apache vhost configuration: SetEnvIf X-Forwarded-Proto "^https$" HTTPS=on

Which I have done and it had no effect.

1

1 Answers

1
votes

I wrote a blog post about the subject a couple of years ago. Please have a look: https://feryn.eu/blog/mixed-content-and-err-too-many-redirects-in-wordpress/

Of course I'm going to put the relevant configuration out here as well.

Nginx config

Nginx is acting as your TLS termination point, but it sends plain HTTP requests to Varnish.

You need to send an X-Forwarded-Proto header through Varnish and Apache, to make both of them aware of the protocol that was used.

You can add the following line to your proxy logic within your Nginx config:

proxy_set_header X-Forwarded-Proto $scheme;

Apache config

Apache will process this X-Forwarded-Proto and perform redirection if the value is not HTTPS.

The snippet below can be dropped in an .htaccess file if you want:

SetEnvIf X-Forwarded-Proto "https" HTTPS=on
Header append Vary: X-Forwarded-Proto

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{HTTPS} !=on
  RewriteCond %{HTTP:X-Forwarded-Proto} !https [NC]
  RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

A quick rundown of what this does:

  • Check the value of the X-Forwarded-Proto
  • Set the environment variable HTTPS to ON if X-Forwarded-Proto equals HTTPS
  • Set a custom Vary: X-Forwarded-Proto header (required for Varnish)
  • Do on HTTPS redirect if HTTPS is not On and X-Forwarded-Proto is not HTTPS

What about Varnish?

By default, Varnish has no protocol awareness. You can write some VCL to make that happen, but luckily the HTTP protocol has the required semantics to make this happen using HTTP headers.

In the previous section about Apache configuration, I referred to Vary: X-Forwarded-Proto. This is what Varnish needs to make a distinction between HTTP & HTTPS content.

If it weren't for this Vary header, Varnish would cache whatever is called first, which could lead to mixed content being cached.

A Vary tells Varnish to create a cache variation for each value of X-Forwarded-Proto. This will separate HTTP content from HTTPS content and will result in the right URL scheme to be used on the cached pages.