I have a certain setup with a Varnish5 caching reverse proxy, with nginx to terminate SSL connections.
The problem with this setup is that wordpress can’t detect https, hence, it can not enforce it, nor will it link the CSS accordingly etc…, and if your blog’s address starts with https, you have a problem.
there is more than one solution that i will enumerate here, I chose to force all connections to come through https (The first), but there are others, the one i will present here (Which i did not use) resolves the problem and allows wordpress to detect whether we are on a secure connection or not.
And even though this post-article talks about wordpress, everything here can apply to any PHP application (Or even other applications written in different programming languages)
1- Enforce https for the whole website
The simplest way to solve the problem (Which i chose) is to redirect all traffic to https.
in the varnish script, implement the following
in the sub vcl_recv, implement the following
if (req.http.host ~ "^(www\.)?example\.com$")
{
if (req.http.host ~ "^(?i)example.com" || req.http.X-Forwarded-Proto !~ "(?i)https") {
return (synth(750, ""));
}
}
Now, the following section is the sub vcl_synth
sub vcl_synth {
if (resp.status == 750) {
set resp.status = 301;
set resp.http.Location = "https://www.example.com" + req.url;
return(deliver);
}
}
Once the above is in place in the varnish script, You will need to tell wordpress that it’s all HTTPS (SSL)
We do that in the config file, the only file we know that does not change when we update
define('FORCE_SSL_ADMIN', true);
$_SERVER['HTTPS']='on';
Now, the above should do it if you don’t mind that your website only works in https, if you do want http to remain an option, then here is another solution
Start by creating a phpinfo() page to check whether you have the $_SERVER[‘HTTP_X_FORWARDED_PROTO
‘] variable , if you do, your work is partially done, but you need to mind too things
the varnish server needs to only cache the https copy (because most browsers won’t allow mixed content these days, and if the css is linked to as http, it won’t display correctly), you can do that easily with something like the following in the vcl_hash
area
if (req.http.X-Forwarded-Proto) {
hash_data(req.http.X-Forwarded-Proto);
}
And then, also in the wp-config file, add the following (probably almost anywhere)
if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
$_SERVER['HTTPS']='on';