Wordpress get_template_directory_uri() behind load balancer - wordpress

I have a Wordpress website running on an AWS EC2 instance. This is served through an AWS Elastic Load Balancer, which has HTTPS enabled with a certificate I got from Amazon.
The intention is to serve both an http and an https version of the website. Loading the http version works fine.
When I load the https version however, I'm getting mixed content errors because get_template_directory_uri() always returns http links. The way the load balancer works is the TLS terminates at the LB, and it communicates with the actual EC2 instance over port 80. therefore, there is no HTTPS on the instance itself.
A lot of this is beyond my skill to heal. I know just enough to have figured out what the problem seems to be, but I'm really not sure what the right way to fix it is.
Assuming I still want to serve both http and https versions of the page (there is no ecommerce or auth on the page -- it's just informational), how should I go about fixing this?
FYI, the EC2 instance is running on an Amazon ABI, which is basically RHEL.

So first off, you will find it difficult to run both an http and https WordPress version off the same database data because WordPress saves a lot of links as absolute links (i.e. with the http(s)://mydomain.com part) and a lot of plugins just don't bother adapting to the current protocol either.
Your best bet is going to be doing redirects through your htaccess file to redirect all http traffic to https.
That being said, one way you could do what you asked for is through a filter used by get_template_directory_uri:
add_filter('template_directory_uri', 'smart_template_directory_uri', 10, 3);
function smart_template_directory_uri($template_dir_uri, $template, $theme_root_uri) {
return preg_replace('/^https?\:/i', '//', $template_dir_uri); // replace "http://" or "https://" by "//", which browsers will automatically set to the current page's protocol
}
Hope this helps!

Related

How to set up a Google VM (instance grouped), https load balanced w/CDN, so that the backend resolves the domain?

Backend: "Bitnami WordPress with NGINX and SSL Stack for Google Cloud Platform" from marketplace.
I used this guide: https://www.am22tech.com/google-cloud-cdn-wordpress/
I ended up with a somewhat working system as follows:
My Domain ->(google managed cert)-> CDN + Load Balancer -> Instance Group ->(http)-> VM with bitnami stack.
All works well and seems very fast. The biggest gap in my understanding is how the VM can be told it needs to behave as if it's the original domain.
For example, in the nginx server config, any kind of reference to $host seems to return the VM's IP address or something like that.
Also, in wordpress, in a lot of places the domain is replaced by an IP address, even though the site URL and wordpress address show up correctly. This isn't a wordpress question though, as I'm quite sure there is a more general solution I'm missing to do perhaps with NGINX or the load balancer configuration. I think PHP detects the host and passed it along to wordpress but I'm not clear how.
I found a reference somewhere in the google documentation how to manually assign a domain to a VM but not sure that's what's needed here.
Further to this, I'm totally unclear how I would set up https between the vm and the load balancer, yet only have one domain/ip address for the global forward rule. Maybe a separate question.
Bitnami Engineer here. If you already have the domain, certificates and the Load Balancer in place, you will need to configure WordPress to use that domain name as default domain of the application. You will need to edit the wp-config.php file and configure these lines
define('WP_SITEURL', 'http://DOMAIN/');
define('WP_HOME', 'http://DOMAIN/');
More info: https://docs.bitnami.com/google/apps/wordpress-pro/administration/configure-domain/
In case you also want NGINX to redirect you your domain, no matter how you access your app's information, you can add this configuration line
return 301 https://DOMAIN$request_uri;
in the /opt/bitnami/nginx/conf/bitnami/bitnami.conf file
More info: https://docs.bitnami.com/google/apps/wordpress-pro/administration/force-https-nginx/
I had better luck having the load balancer talk to my VM with https. Once I got that working, I didn't have to make any changes to wp-config.php. In this case I didn't bother with varnish because I think it only supports http. I'm hoping google's CDN will be sufficient regarding caching, and I may try a helper plugin in wordpress.
To redirect http to https, I followed the bitnami instructions to set up to front ends to the load balancer pointing to the same static ip address, then in my nginx server blocks, I added a redirect line in the https block (not the http block), since the google load balancer communicates with my backend via https. Google sets the http_x_fowward_proto to http so I check that and redirect if necessary.
if ($http_x_forwarded_proto = "http") { return 301 https://$host$request_uri; }
The bitnami stack is amazing, everything seems extremely fast!

Iptables for Wordpress site

Usually when we configure iptables rules for a website, we accept incoming connections to HTTP and HTTPS ports.
In the case of Wordpress, the CMS also makes HTTP and HTTPS connections to wordpress.org (for example, when you search for a plugin in the dashboard or you try to make an update of Wordpress)
HTTP/HTTPS connections are also needed when upgrading your system via apt-get or yum.
Since I am not comfortable just allowing all HTTP/HTTPS outgoing connections from a server, do you have any ideas on how to let you system or Wordpress make HTTP/HTTPS connections in a safer manner?
Regards,
You can make WordPress use a proxy for outgoing connections, if you don't mind running one somewhere, which would also allow you to filter the traffic to catch misbehaving plugins. You might run into trouble with older plugins that don't use the HTTP API, but I haven't met any in quite some time.

Url rewriting with Charles Proxy in order to run a wordpress site over a LAN?

I want to use Charles Proxy to share a local development PC's web server where I am developing sites on so that I can access the PC over my LAN to test on various mobile devices.
Having setup the correct ip address of my PC in the http proxy settings on various tablets they can all connect to the PC and this works fine.
The issue is that I need to test a wordpress site and as anyone that uses wordpress knows, it generates full url links between each page it serves. As the site normally runs on my PC the urls it generates are all http://localhost/wordpress/pagename.
So the issue is that if I access the same site from a remote device via the proxy (addressing http://192.168.1.200/wordpress/) it instantly redirects me to http://localhost/wordpress/pagename url in the mobile device and this fails to load as the tablet can't determine "localhost" correctly.
There must be a way of using one of Charles' various options to resolve this but I can't for the life of me work out which. I've tried remote maps and DNS spoofing but no joy.
Note, I'm completely aware that you can with SQL commands change the urls throughout a wordpress database but I just wanted to see if this was possible without undertaking this step as it would be a lot more flexible if I don't have to do that each time I want to preview sites via my other local LAN devics.
You can use Charles proxy feature called Rewrite Tool. I assume your local network uses 192.168.168.X IPs.
Enable rewrite
Add new rule and name it as you wish
To Locations section add Protocol: http and Host: 192.168.168.X
To Rules section add Type: body, Where: response, Match: localhost, Replace: 192.168.168.X
It may require some more tinkering but i hope you get the idea

Windows Azure VM SSL and Cloudapp.net

I installed an ASP.net application on a windows Azure VM (IIS 7). SSL certificate is installed, configured and the application works correctly. I have removed Http binding and http endpoints.
The issue I am having is that if I use the cloudapp.net link (using https), the application still opens with a mismatched certificate.
What can I do to deny any user from opening my application using https://xx.cloudapp.net/x?
It seems really silly that people are saying this isn't the right place for this question, since some of the solutions could be code related. ie: In your application, check the host and if it's cloudapp.net, do a URL redirect.
There's a few different options here but it sounds like what you're looking for is just the ability to prevent someone from viewing the application using that URL.
What I would do is set up a site in IIS that uses Host Header resolution to look for xx.cloudapp.net. If that URL is recognized, do a redirect using the HTTP redirect settings to the https version of your app. Don't bind the SSL port to this site or you'll run into SSL errors like you showed above.
The other option is to leave it out entirely and simply use the Host Header resolution to filter out requests for your site. I suspect what you've done is assign all incoming requests to the only IP address on the system, which is why the xx.cloudapp.net is showing your app and the cert is failing.
This would cause xx.cloudapp.net to fail to show any site at all but I think that might be what you want to do anyway.

Should I always use a reverse proxy for a web app?

I'm writing a web app in Go. Currently I have a layout that looks like this:
[CloudFlare] --> [Nginx] --> [Program]
Nginx does the following:
Performs some redirects (i.e. www.domain.tld --> domain.tld)
Adds headers such as X-Frame-Options.
Handles static images.
Writes access.log.
In the past I would use Nginx as it performed SSL termination and some other tasks. Since that's now handled by CloudFlare, all it does, essentially, is static images. Given that Go has a built in HTTP FileServer and CloudFlare could take over handling static images for me, I started to wonder why Nginx is in-front in the first place.
Is it considered a bad idea to put nothing in-front?
In your case, you can possibly get away with not running nginx, but I wouldn't recommend it.
However, as I touched on in this answer there's still a lot it can do that you'll need to "reinvent" in Go.
Content-Security headers
SSL (is the connection between CloudFlare and you insecure if they are terminating SSL?)
SSL session caching & HSTS
Client body limits and header buffers
5xx error pages and maintenance pages when you're restarting your Go application
"Free" logging (unless you want to write all that in your Go app)
gzip (again, unless you want to implement that in your Go app)
Running Go standalone makes sense if you are running an internal web service or something lightweight, or genuinely don't need the extra features of nginx. If you're building web applications then nginx is going to help abstract "web server" tasks from the application itself.
I wouldn't use nginx at all to be honest, some nice dude tested fast cgi go + nginx and just go standalone library. The results he came up with were quite interesting, the standalone hosting seemed to be much better in handling requests than using it behind nginx, and the final recommendation was that if you don't need specific features of nginx don't use it. full article
You could run it as standalone and if you're using partial/full ssl on your site you could use another go http server to redirect to safe https routes.
Don't use ngnix if you do not need it.
Go does SSL in less lines then you have to write in ngnix configure file.
The only reason is a free logging but I wonder how many lines of code is logging in Go.
There is nice article in Russian about reverse proxy in Go in 200 lines of code.
If Go could be used instead of ngnix then ngnix is not required when you use Go.
You need ngnix if you wish to have several Go processes or Go and PHP on same site.
Or if you use Go and you have some problem when you add ngnix then it fix the problem.

Resources