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

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

这是我的简化的 nginx vhost 配置:

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 服务器上设置,但这样我就必须复制其余的配置文件(server为了简单起见,我省略了指令中的许多内容)。我知道我也可以使用include指令来消除冗余,但我真的想保留一个没有任何依赖项的配置文件。

那么,首先,我是否遗漏了某些可以完全消除问题的东西?或者,其次,如果没有,是否有其他方法(除了包含外部文件)来提取冗余配置信息,以便我可以分离出服务器配置的 HTTP 和 HTTPS 版本?

答案1

好吧,我得到了一些灵​​感并尝试了:

proxy_redirect http:// $scheme://;

这似乎奏效了。不过,这对我来说仍然似乎有点不靠谱,因此我仍然欢迎任何有关我可能做错的事情的指导,或者以不那么不靠谱的方式实现相同结果。

答案2

另一个解决方案是向上游指示请求是 HTTP 还是 HTTPS,并让上游发出相应的重定向。在 nginx 配置中添加此项将设置上游要检查的标头。

proxy_set_header    X-Scheme $scheme;

相关内容