我可以使用Nginx重定向SSL端口上的非SSL流量

Hug*_*own 13 nginx

我有一个相当标准的设置与nginx前面的django应用程序.我希望django应用程序只是SSL,所以我的nginx conf中有两个监听块,端口80(HTTP)上的流量被重定向到端口443(SSL).这是按预期工作的.

我在启用了端口转发的VM中运行此设置,以便我可以通过转到端口8080(HTTP)或8081(SSL)从主机浏览该站点.再次,这工作正常,如预期的那样.

当我在注册工作流程中从Django应用程序内部重定向时,问题就出现了.因为Django从未看到SSL状态(SSL在nginx处终止,并且应用程序的流量通过HTTP在端口5000上转发),但确实看到了端口,重定向正在被破坏**.

所有这一切的最终结果是我将流量引导到SSL端口上的nginx,即不是SSL,例如http://127.0.0.1:443/.有没有办法配置nginx来处理这个?

**NB我在Nginx中设置了X-Forwarded-Proto标头,而Django正在获取正确的.is_secure()值,这是一个特定的问题,外部库没有检查is_secure,只是重定向传入的URL方案.

[更新1]

附件是相关的配置设置.这是来自Vagrantfile本身,显示端口转发:

config.vm.forward_port 80, 8080     # website, via nginx (redirects to SSL:8081)
config.vm.forward_port 443, 8081    # website, via nginx (accepts SSL)
config.vm.forward_port 5000, 8180   # website, via gunicorn (direct)
Run Code Online (Sandbox Code Playgroud)

使用上述端口转发配置,如果我在HTTP端口(8080)上浏览到主机上的站点,则接受请求,并且nginx(见下文)将此请求重定向到HTTPS(在端口8081上运行).一旦我使用HTTPS,网站本身就可以正常工作:

(host) http://127.0.0.1:8080  -> forwarded to -> (guest vm) http://127.0.0.1:80  
(host) https://127.0.0.1:8081 -> forwarded to -> (guest vm) https://127.0.0.1:443
Run Code Online (Sandbox Code Playgroud)

当我从Django内部获得一个混合方案和协议的重定向,并最终得到一个请求http:\\127.0.0.1:8081\...失败,因为nginx期望8081上的流量是SSL时,会出现问题.

我真正想要的是一条规则,即"在443上监听SSL和非SSL以及重定向非SSL".

这是相关的nginx配置:

# Django app is served by Gunicorn, running under port 5000 (via Foreman)
upstream gunicorn {
    server 127.0.0.1:5000 fail_timeout=0;
}

server {
    listen 80;
    # 8081 is the port I am forwarding to on the host machine
    rewrite ^ https://127.0.0.1:8081$request_uri? permanent;
}

server {
    listen 443;

    ssl on;
    ssl_protocols       SSLv3 TLSv1;
    ssl_ciphers         HIGH:!ADH:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_certificate     /etc/nginx/ssl/self-signed.crt;
    ssl_certificate_key /etc/nginx/ssl/self-signed.key;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location /static/ {
        alias /app/static/;
    }
    location /media/ {
        alias /app/media/;
    }
    location / {
        # everything else is to be served by the django app (upstream 'gunicorn')
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # this is set to ensure that django is_secure returns True
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $http_host;
        proxy_pass http://gunicorn;
    }
}
Run Code Online (Sandbox Code Playgroud)

And*_*lov 22

您应该查看本文档的"错误处理"部分:

http://nginx.org/en/docs/http/ngx_http_ssl_module.html

非标准错误代码497可用于处理已发送到HTTPS端口的纯HTTP请求.

这样的东西应该工作(未经测试):

error_page 497 https://$host$request_uri;
Run Code Online (Sandbox Code Playgroud)

命名位置也可以在error_page中使用,有关详细信息,请参见http://nginx.org/r/error_page.