19

New to nginx. Played with it for 2 days and cannot figure out how to solve this:

I have a bunch of VMs running in one box, the box is behind my router obviously, one of the VMs is running nginx(my reverse proxy) and is set as DMZ.

I have got SSL certificate installed on that VM properly, now I want all incoming traffic to be directed according to their path, e.g.:

domain.com/service1->192.168.1.101

domain.com/service2->192.168.1.102

And so on. Idea is to let nginx work as the SSL layer and nginx talks to other VMs via HTTP or whatever protocols unencrypted. Then of course when nginx talks back to the client, the messages shall be encrypted.

I have got that partially working. If I access via HTTP everything is fine except not encrypted, but if I access via HTTPS the web pages are broken and I got this kind of error: Mixed Content: The page at 'https://domain.com/service1' was loaded over HTTPS, but requested an insecure stylesheet 'http://domain.com/service1/blahblah.css'. This request has been blocked; the content must be served over HTTPS.

I also got this kind of warning: The page at 'https://domain.com/service1/' was loaded over HTTPS, but is submitting data to an insecure location at 'http://domain.com/service1/': this content should also be submitted over HTTPS.

Now, for some of the services I can hack the service itself so it can get fixed...but I do not want to do that, because then I have to hack every service which is time consuming and can potentially break something. I want to touch the services as little as possible.

My current configuration works with the hack but does not work without hack. It covers the whole service1:

location /service1/ {
    proxy_pass              http://192.168.1.101/;

    proxy_read_timeout      3500;
    proxy_connect_timeout   3250;

    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        Host $host;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Proto https;

    proxy_set_header        SSL_PROTOCOL $ssl_protocol;
}

I looked around the internet for a general solution but only found one hack that worked for one service. Other nginx examples/howtos did not help much(still getting the errors and warnings).

Many thanks in advance!

HBruijn
  • 77,029
  • 24
  • 135
  • 201
anetworknoobie
  • 193
  • 1
  • 1
  • 5
  • This has nothing to do with nginx, using a reverse proxy or anything directly web-server related. The problem is the **contents** of served html. There is, for example `
    – AD7six Jan 13 '15 at 15:30
  • If you are still looking for a solution please see the answer by Henry Chan in this thread https://serverfault.com/a/1070930/979086 – MarkAddison Aug 07 '22 at 11:29

6 Answers6

25

This worked for nginx https proxy >> nginx http serving Django backend

Inside a location directive:

proxy_set_header X-Forwarded-Proto $scheme;

For more details it's worth to read this excellent article: https://www.metaltoad.com/blog/running-drupal-secure-pages-behind-proxy

user2158987
  • 351
  • 3
  • 3
20

With nginx, I needed:

        add_header 'Content-Security-Policy' 'upgrade-insecure-requests';
Henry Chan
  • 301
  • 2
  • 2
  • 1
    how's about more context?? – djdomi Jul 28 '21 at 19:20
  • 1
    this should be the correct solution!. – Mahmoud Kassem Oct 07 '21 at 13:40
  • @djdomi https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade-Insecure-Requests – J. Scott Elblein Nov 12 '21 at 03:05
  • 1
    @djdomi The `upgrade-insecure-requests` declare that browsers should transparently upgrade HTTP resources on a website to HTTPS. – Annahri Nov 13 '21 at 22:22
  • 1
    If one is using Nginx as reverse-proxy, this should be put inside the server block (not inside the location block where proxy_pass is put). By using this header, one would skip editing the app source code. – Annahri Nov 13 '21 at 22:24
  • I am so thankful that I found this answer. I have been seeking a solution to this problem for quite a long time!! **Moderator(s) - Please mark this as the correct solution.** – MarkAddison Aug 07 '22 at 11:27
9

You have to go through the sites' code, and replace all occurences of http://domain.com/resource with either /resource or //domain.com/resource.

This ensures that all the dependent web page resources are loaded with the same protocol as the website itself is loaded.

Tero Kilkanen
  • 36,796
  • 3
  • 41
  • 63
  • 4
    Does it mean nginx cannot rewrite outgoing packets? I hate tinkering every site behind it... – anetworknoobie Jan 14 '15 at 03:06
  • There could be a 3rd party module that might be able to do something like that. The problem is that it is much more complex and CPU intensive to rewrite links in a bytestream coming out from a backend than rewriting HTTP requests coming from a client. It is best to fix the sites. – Tero Kilkanen Jan 14 '15 at 03:10
  • @anetworknoobie you _could_ use [sub filter](http://nginx.org/en/docs/http/ngx_http_sub_module.html) - but you'd be a whole lot better off not to. – AD7six Jan 14 '15 at 12:11
4

Adding to this apache.conf file fixed my issue

 <IfModule mod_setenvif.c>
  SetEnvIf X-Forwarded-Proto "^https$" HTTPS
</IfModule>
David Okwii
  • 324
  • 1
  • 5
  • 13
0

I might be late by half a decade, but I faced the issue recently and for me the solution was setting in HTML page:

<base href="/" />
  • and what should we have understood from this? – EgoPingvina Jul 15 '20 at 12:30
  • Sometimes the nginx configuration or any server configuration setup is not the issue. Especially if you work with single page applications like AngularJS. In my case adding the above code into index.html solved this issue. – Sree Menon Jul 27 '20 at 03:31
0

In settings.php, set

$base_url='';

But bootstrap will show you error on it, so change the below code in /var/www/includes/bootstrap.inc

if (isset($base_url)) { 
//change to 
if (isset($base_url) && $base_url!='') {
dawud
  • 15,096
  • 3
  • 42
  • 61