Mixed content error while serving wordpress from another instance - wordpress

I want to serve a WordPress application from https://example.com/blog. The issue is that https://example.com is hosted on another instance and I am redirecting /blog to other instance. The server I am using is Nginx. This is my Nginx configuration.
server {
server_name example.com;
location / {
try_files $uri $uri /index.html;
}
location ^~ /blog {
proxy_pass http://<IP>/blog;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
allow <IP>;
}
}
As the /blog is running on other instance it is giving me Mixed-content errors because the proxy is passed to http:IP and it is loaded over https. Please help me solveing this issue.

$_SERVER['HTTPS'] needs to be set to on in case you're accessing it through proxy_pass and deliver it via HTTPS. Otherwise, WordPress knows it's forwarded, but cannot check whether it's delivered via HTTP or HTTPS to the outside. Add these lines to your wp-config.php file:
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$_SERVER['HTTPS'] = 'on';
}
Please note that if there are multiple proxies and one of those doesn't serve HTTPS, you have to make that condition based on what HTTP_X_FORWARDED_FOR actually contains. For now, we're only checking if it's non-empty and by that we assume it's supposed to be HTTPS.

Related

How can I do a 301 redirect towards an URL ending in a slash with Nginx?

I've an nginx web server that proxy pass traffic to different services on my LAN. After a recent update of one of those services the redirect stop working as expected. The service behind the redirect is Pi-Hole so I can't/wan't modify how the web service works. I just want to fix the redirect.
My actual nginx configuration looks like this:
server {
listen 80;
listen [::]:80;
server_name servername.xyz localhost default;
access_log /var/log/nginx/servername-xyz.access.log;
error_log /var/log/nginx/servername-xyz.error.log;
location = /pihole {
return 301 http://servername.xyz/pihole/admin;
}
location = /pihole/ {
return 301 http://servername.xyz/pihole/admin;
}
location /pihole/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://127.0.0.1:31480/;
}
location = / {
return 418;
}
}
This configuration was working perfectly. Every time I write in my browser http://servername.xyz/pihole, I automatically get the redirect to http://servername.xyz/pihole/admin and start using the Pi-Hole web console flawless.
With the last Pi-Hole update, they make a small change that broke the redirect. Now every time you ask for http://pi-hole.domain/admin the web console is automatically redirected to http://pi-hole.domain/admin/. Note the slash at the end of the second URL.
In my configuration, that means the following behaviour:
I ask the browser for http://servername.xyz/pihole
I get the 301 and go to http://servername.xyz/pihole/admin
Here I get a redirect that I don't expect from the Pi-Hole web console that makes me go to: http://servername.xyz/admin/. Note the ending slash.
When I get to the third step, the redirect doesn't allow me to get into the Pi-Hole web console. I've tried some changes to the rules, but I didn't succeed in my objective to get a 301 towards http://servername.xyz/admin/ to avoid the Pi-Hole web console redirect.
Big thanks to Richard's Smith comment. It let me fix the configuration file. Now the proxy_pass action in the file looks like:
location /pihole/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://127.0.0.1:31480/;
proxy_redirect http://servername.xyz/admin/ http://servername.xyz/pihole/admin/;
}
After including the proxy_redirect directive, things start working again.

nginx reverse proxy - only allow access with "secret token"

I have set up a reverse proxy with the following code in nginx:
server {
listen 80;
server_name domain.com;
server_name www.domain.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://ip-of-server:80;
}
}
Is it possible to let users only access my main server via domain.com/?some-secret-token and not let them access it if they are going to domain.com directly? In best case, the secret-token would also disappear from URL after they open it. I know it would be possible within my homepage script - but can I also configure my nginx in such a way without changing script files?
Don't think this is possible with pure nginx. You can, however, set up basic authentication on your url with something like this after you've properly configured a .htpasswd file:
location / {
auth_basic "Private";
auth_basic_user_file /etc/nginx/.htpasswd;
}
Full details of how to set this up are available here.

nginx Reverse Proxy with plesk

I've already seen some answers on here and none of the solutions seem to work.
I have domain.com with a wordpress install
and a script running on domain.com:6000
I want to be able to have script.domain.com show what's on domain.com:6000
Now the other big issue is plesk. (It gets a lot of hate but the people using the website like the UI.) but here's what I've done/tried
New folder and file in /var/www/vhosts/domain.com/conf
file : vhost_nginx.conf
and what's currently in it
server {
listen 80;
server_name script.domain.com;
location / {
proxy_pass http://domain.com:6000;
}
}
Also having tried
location /script/ {
proxy_pass http://domain.com:6000/;
}
to try and have domain.com/script show something different.
Any suggestions?
Right now in PLesk 12.5 there is no way to override "location /" via plesk, because all custom conf files are added at the end of nginx's server section after default "location /" derectives.
You can create or change hosting type of your subscription to forwarding like in this answer https://serverfault.com/a/541055/154664
But in this case port will be visible in URL.
Another solution is to create your own custom virtual host in nginx in some separate config - it's actually easiest way now.
Another solution is to customize virtual hosting templates, but it's too much side effects on Plesk upgrade.
I put this in the Plesk UI under additional nginx directives and it worked for me. You can remove the if, if you are ok with http traffic. Also replace <*> accordingly. For instance:
<your-domain> = script.domain.com, <your-host> = localhost <your-port> = 6000
if ($scheme = http) {
return 301 https://<your-domain>;
}
location ~ / {
proxy_pass http://<your-host>:<your-port>;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}

Rewriting redirects to include the port used to access the service

I have a setup like this:
A user working with my Vagrant development environment accesses localhost:8080 on their host machine, which is forwarded into Vagrant to NGINX running at localhost:80 on the guest. Some requests are forwarded into my application server running at localhost:8080 on the guest, and some are static files served from NGINX.
A weird thing happens when I access my site. I have a login page which redirects on success, and the URL is rewritten from http://localhost:8080/login to http://localhost:80/login.
Here's my NGINX configuration for the site:
upstream appserver {
server 127.0.0.1:8080;
}
upstream production {
server www.mysite.com:443;
}
server {
listen 80 default_server;
server_name _;
client_max_body_size 20M;
access_log /var/log/nginx/project.access.log;
error_log /var/log/nginx/project.error.log;
index /index;
location ~ ^(/js/testpage.js) {
alias /vagrant/artifacts/www/js/testpage.js;
}
location ~ ^(/test/js/app.js) {
alias /vagrant/test/js/app.js;
}
location ~ /test/js/app_router.js {
alias /vagrant/test/js/app_router.js;
}
location ~ /test/js/app_layout_controller.js {
alias /vagrant/test/js/app_layout_controller.js;
}
location ~ /test/js/apps/navbar/sections/layout/navbar_layout_controller.js {
alias /vagrant/test/js/apps/navbar/sections/layout/navbar_layout_controller.js;
}
location ~ /test/js/apps/navbar/sections/navbar/navbar_options_view.js {
alias /vagrant/test/js/apps/navbar/sections/navbar/navbar_options_view.js;
}
location ~ /test/js/apps/navbar/sections/navbar_all_views.js {
alias /vagrant/test/js/apps/navbar/sections/navbar_all_views.js;
}
location ~ ^/test/js/apps/(.*/testpage_.*\.js)$ {
alias /vagrant/test/js/apps/$1;
}
location ~ ^/test/js/(.*)$ {
alias /vagrant/js/$1;
}
location ~ ^/build/js/(.*)$ {
alias /vagrant/artifacts/www/js/$1;
}
location ~ ^/build/css/(.*)$ {
alias /vagrant/artifacts/www/css/$1;
}
location ~ ^/(.*main.*)\.[#\-_\/\d\w]+\.(js|css)$ {
alias /vagrant/$1.$2;
}
location ~ ^/(css|js|fonts|favicon.ico) {
root /vagrant;
}
location ~ ^/receipts/js/(.*)$ {
alias /vagrant/receipts/js/$1;
}
location ~ ^/bower_components/(.*)$ {
alias /vagrant/bower_components/$1;
}
location ~ ^/login-promo/ {
access_log off;
proxy_pass https://production;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~ ^/(admin|login|logout|index|build|testpage|receipts|open|reset|resetpage|privacy|change|activeUser|personPrivacyAcceptances) {
access_log off;
proxy_pass http://appserver;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
I'm not sure where the redirect is actually coming from, it could be coming from the app server backend or from the front end JavaScript. Is there a way that I can make sure that all redirects take the port used by the accessing client?
Update: Simply adding a login link to the root page and trying to navigate with that link redirects me to http://localhost:80/login rather than http://localhost:8080/login.
This is probably an undesired side-effect of fowarding the guest's nginx port to a different one on the host.
See http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect
Desactivating the proxy redirection in the last location block should do the trick:
proxy_redirect off;
It's likely happening due to port_in_redirect being on by default. See: http://wiki.nginx.org/HttpCoreModule#port_in_redirect
Disabling that would likely stop some of the confusion as to why the port is being applied.
From there, it's a simple as setting the appropriate host_port or remote_port in your proxy pass redirects, as necessary. By looking at your config, it seems you are comfortable using the core module variables, it would be quite simple to include those variables.
See:
http://wiki.nginx.org/HttpCoreModule#.24remote_port
http://wiki.nginx.org/HttpCoreModule#.24server_port
This seems to have been caused by doing redirects wrong in application code.
If you have a similar architecture as above and are experiencing the problem, it's likely that the reason you're experiencing the problem is because of a naive attempt at redirecting without accounting for the Host header.
Your application behind nginx sees a request like this:
GET /path/to/resource
Host: virtualinstance:8888
Unfortunately, when it constructs the redirect, it does something dumb and reconstructs the redirect without taking into account the Host header, instead opting for the host and port which it knows it is using. The code that was breaking my redirect looked something like this:
return redirect("http://" + getHostName() + "/" + getPath())
First, it's bad that it hardcodes the protocol, but worse yet that it uses a method which gets the host name without regard for the port. This would return a redirect to http://localhost/path, rather than http://localhost:8888/path.
Developers, this is why you should always use the Host header as a source for your redirect:
return redirect("%s://%s/%s" % (getProtocol(), getHeader("Host"),
getPath())
This makes a sane redirect, using the original protocol, full text from Host, and the path.

Nginx: How to forward requests to a port using proxy_pass

I'm just getting started with Nginx and am trying to set up a server block to forward all requests on the subdomain api.mydomain.com to port 8080.
Here's what I've got:
UPDATED:
server {
server_name api.mydomain.com;
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-for $remote_addr;
}
}
server {
server_name www.mydomain.com;
return 301 $scheme://mydomain.com$request_uri;
}
server {
server_name mydomain.com;
root /var/www/mydomain.com;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
The server block exists in /etc/nginx/sites-available and I have created a symlink in /etc/nginx/sites-enabled.
What I expect:
I'm running deployd on port 8080. When I go to api.mydomain.com/users I expect to get a JSON response from the deployd API, but I get no response instead.
Also, my 301 redirect for www.mydomain.com is not working. That block was code I copied from Nginx Pitfalls.
What I've tried:
Confirmed that mydomain.com:8080/users and $ curl
http://127.0.0.1:8080/users return the expected response.
Restarted the nginx service after making changes to the server block.
Tried removing the proxy_set_header lines.
Any idea what I'm missing here?
You shouldn't need to explicitly capture the URL for your use case. The following should work for your location block:
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
}
As it turns out, my problem was not with Nginx configuration but rather with my DNS settings. I had to create an A NAME record for each of my sub-domains (www and api). Rookie mistake.
A colleague of mine actually helped me troubleshoot the issue. We discovered the problem when using telnet from my local machine to connect to the server via IP address and saw that Nginx was, in fact, doing what I intended.

Resources