Putting together Wordpress, Unitd and https

Alex Povolotsky
2 min readDec 19, 2020

Recently, I’ve got a simple task of setting up an empty site to be filled. Wordpres… well, just a wordpress.

Easy as a cake, yes?

(skipping installing nginx, php, requires extensions, certbot. On your favorite system in takes 3–5 simple commands and some time to work it out)

Why unitd? Well, why not? I just like it more than php-fpm. Let’s assume we have to use it.

Official instructions looks simple, but it stops one step before finish. https.

I’ve installed, configured, made basic setup, added ssl certificate and garbled my site to the point I could not get anything usable from admin panel. I’ve got Mixed Content Error.

I won’t explain it in details, there are more articles on the subject than one can read in his life; the only thing that is of any use is that’s intolerable.

Ok, let’s do from scratch! (note to any sane IT personnel: writing from scratch should be your last resort, not the first) Woops. Nothing happened.

After some time, I’ve made a simple info.php (<?php phpinfo(); ?>) and tried it (don’t forget to remove after finishing the work! May reveal sensitive information) — to find out that request came from 127.0.0.1, by http. Well, at least I know whom to blame (myself, I should remember that unitd has currently no provision to set remote_ip to real remote_ip).

There is an is_ssl() function over there in ./wp-includes/load.php, hammering it down to return true gave me access to admin page; not good after all.

But (a) it’s ugly (b) it will be overwritten during the next upgrade (c) I’d better fix REMOTE_ADDRESS as well.

But now, understanding what to fix, I’ve easily found out

in nginx.conf

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

in wp-config.php

/* === https and remote_address === */
if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ) {
if ( 'https' == $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
$_SERVER['HTTPS'] = 'on';
}
}
if ( isset( $_SERVER['HTTP_X_REAL_IP'] ) ) {
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_REAL_IP'];
}
/* === https and remote_address === */

Easy as a cake, yes?

Kinda.

When cleaning up, I’ve found out that is_ssl still hardcoded to return true. Removing hardcode… breaks everything. Setting `$_SERVER[‘HTTPS’] = ‘on’;` in wp-config.php… works, but that’s a hardcode. Putting the code into info.php… works.

As my last resort, I’ve tried to read wordpress source. Up to loading of wp-config, it was straightforward. So there were no hidden `unset()`s, just no way for them.

So it HAD to be in my configs.

Looking at my nginx.conf, I’ve found that index.php is not handled by *.php rule! It has it’s own!

Well. The only thing I had to do a minute later was cleaning up all of my debugging effort.

Be careful. Read, think and do. Not do, google, do, google, do, read, think and do after all.

--

--