django:应用程序使用NGINX与SECURE_SSL_REDIRECT崩溃

时间:2015-11-19 00:06:04

标签: python django ssl nginx ssl-certificate

我正在努力让我的django应用程序在SSL之后工作,使用nginx,gunicorn;所有安装在服务器中,可以在Intranet中访问,但不能从外部访问。这些是我的设置。

settings.py:

...
SECURITY_MIDDLEWARE = ('django.middleware.security.SecurityMiddleware',)
MIDDLEWARE_CLASSES = SECURITY_MIDDLEWARE + MIDDLEWARE_CLASSES

SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTPONLY = True
X_FRAME_OPTIONS = 'SAMEORIGIN'
SECURE_HSTS_SECONDS = 60 
SECURE_BROWSER_XSS_FILTER = True
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_CONTENT_TYPE_NOSNIFF = True

SECURE_SSL_REDIRECT = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')

nginx.conf:

server {
   listen 80;
   server_name HOSTNAME;

   location / {
       proxy_set_header Host $host;
       proxy_pass http://unix:/tmp/HOSTNAME.socket;
       proxy_set_header X-Forwarded-Protocol $scheme;
       rewrite ^ https://$host/$request_uri permanent;
   }
}

想知道是否有人可以指出我正确的解决方案。

2 个答案:

答案 0 :(得分:1)

以防万一,您是否尝试过设置ALLOWED_HOSTS

另外,请阅读此from the docs

  

如果将此设置为True会导致无限重定向,则可能意味着您的站点在代理后面运行,无法确定哪些请求是安全的,哪些请求不安全。您的代理可能会设置标头以指示安全请求;您可以通过找出该标头是什么来更正问题并相应地配置SECURE_PROXY_SSL_HEADER设置。

然后在你的nginx conf中查看你的内容:

listen 80
...
proxy_set_header X-Forwarded-Protocol $scheme;

您确定$schemehttps而不是http吗?您正在侦听端口80,而不是端口443,并且当SECURE_PROXY_SSL_HEADER设置可能正在转发不安全的http请求时,https设置似乎正在等待{。}}。

只是一个猜测,看着配置。

答案 1 :(得分:1)

免责声明:我是网络开发的新手。我也是这个问题的作者。

编辑:在/var/log/nginx/HOSTNAME_error.log中我收到以下错误:

no "ssl_certificate" is defined in server listening on SSL port while SSL handshaking

根据Steve的回答,这个问题(请参阅评论链接)和这个blog,我终于让我的应用程序在SSL背后工作。

我使用以下命令创建了SSL证书和密钥(像我这样没有经验的用户会注意到这些证书是自签名的,因此浏览器将连接归类为不安全。但是事务已正确加密。有关该命令的更多信息,请参阅blog):

dzdo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt

将我的nginx.conf更改为(因为我使用的是DjangoWhiteNoise,我的nginx conf不会处理静态媒体文件):

server {
    listen          80;
    server_name     HOSTNAME;
    rewrite ^/(.*)  https://HOST/$1 permanent;
}

server {
    listen 443 ssl;
    server_name     HOSTNAME;
    access_log      /var/log/nginx/HOSTNAME_access.log combined;
    error_log       /var/log/nginx/HOSTNAME_error.log error;

    # To create an SSL certificate:
    # dzdo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt

    ssl_certificate /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx.key;

    location / {
        proxy_pass         http://unix:/tmp/HOST.socket;
        proxy_redirect     off;
        proxy_set_header   Host              $http_host;
        proxy_set_header   X-Real-IP         $remote_addr;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }

}

最后,我将Django安全设置设置为:

...
SECURITY_MIDDLEWARE = ('django.middleware.security.SecurityMiddleware',)
MIDDLEWARE_CLASSES = SECURITY_MIDDLEWARE + MIDDLEWARE_CLASSES

SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTPONLY = True
X_FRAME_OPTIONS = 'SAMEORIGIN'
SECURE_HSTS_SECONDS = 60 
SECURE_BROWSER_XSS_FILTER = True
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_CONTENT_TYPE_NOSNIFF = True

SECURE_SSL_REDIRECT = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')

希望这可以帮助像我这样的人。