用作反向代理时,防止nginx将流量从https重定向到http


16

这是我的缩写nginx vhost conf:

upstream gunicorn {
    server 127.0.0.1:8080 fail_timeout=0;
}

server {
    listen 80;
    listen 443 ssl;
    server_name domain.com ~^.+\.domain\.com$;

    location / {
        try_files $uri @proxy;
    }

    location @proxy {
        proxy_pass_header Server;
        proxy_redirect off;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_connect_timeout 10;
        proxy_read_timeout 120;
        proxy_pass http://gunicorn;
    }
}

同一台服务器需要同时服务HTTP和HTTPS,但是,当上游发出重定向(例如,在处理表单之后)时,所有HTTPS请求都将重定向到HTTP。我发现可以解决此问题的唯一方法是更改proxy_redirect为以下内容:

proxy_redirect http:// https://;

这对于来自HTTPS的请求非常有用,但是如果通过HTTP发出重定向,它也会将其重定向到HTTPS,这是一个问题。

出于绝望,我尝试了:

if ($scheme = 'https') {
    proxy_redirect http:// https://;
}

但是nginx抱怨proxy_redirect这里不允许这样做。

我唯一想到的另一种选择是分别定义两个服务器,并proxy_redirect仅在SSL上设置,但随后我将复制其余的conf(server为简化起见,我省略了很多指令)。我知道我也可以使用一条include指令来排除冗余,但是我真的想只保留一个conf文件而没有任何依赖关系。

所以,首先,我缺少什么可以完全消除问题的东西吗?或者,第二,如果不是,是否还有其他方法(包括外部文件)来排除冗余配置信息,以便我可以区分出服务器配置的HTTP和HTTPS版本?

Answers:


29

好吧,我得到了一些启发,并尝试了:

proxy_redirect http:// $scheme://;

这似乎可以解决问题。但是,对于我来说,这似乎仍然很棘手,所以我仍然欢迎任何指导,无论我做错了什么,还是想用更少的技巧实现相同的结果。


确实,这似乎是做到这一点的“官方”方式...参见wiki.nginx.org/SSL-Offloader
Hendy Irawan

以上指向nginx Wiki的链接不再起作用,新位置为nginx.com/resources/wiki/start/topics/examples/SSL-Offloader
Paul Tobias

如果您所在的位置没有斜杠,这将不起作用
hdave

该死的该死的,为什么软件不能仅仅指望在反向代理之后生存(或至少该死的尊重X-Forwarded-Scheme或其他?)blet +
Axel Latvala

5

另一种解决方案是向上游指示请求是HTTP还是HTTPS,并让其发出相应的重定向。将其添加到nginx配置中将为上游检查设置头。

proxy_set_header    X-Scheme $scheme;

嗯,我现在看到您已经具有该配置。
mgorven 2012年

是的 但是,我仍然感谢您提供帮助的尝试。
克里斯·普拉特

4
这似乎是一些奇怪的标题。我认为X-Forwarded-Proto更好
vladkras
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.