django:应用程序崩溃 SECURE_SSL_REDIRECT 使用 NGINX
django: application crash with SECURE_SSL_REDIRECT using NGINX
我正在尝试使用 nginx、gunicorn 让我的 django 应用程序在 SSL 后工作;都安装在一个可以在内网访问但不能从外部访问的服务器上。这些是我的设置。
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;
}
}
想知道是否有人可以指出正确的解决方案。
为了以防万一,您是否也尝试过设置 ALLOWED_HOSTS
?
此外,正在阅读这篇文章from the docs:
If turning this to True causes infinite redirects, it probably means your site is running behind a proxy and can’t tell which requests are secure and which are not. Your proxy likely sets a header to indicate secure requests; you can correct the problem by finding out what that header is and configuring the SECURE_PROXY_SSL_HEADER setting accordingly.
然后查看 nginx conf 中的内容:
listen 80
...
proxy_set_header X-Forwarded-Protocol $scheme;
您确定 $scheme
是 https
而不是 http
吗?您正在侦听端口 80,而不是端口 443,并且您的 SECURE_PROXY_SSL_HEADER
设置看起来像是在等待 https
可能会转发不安全的 http 请求。
只是猜测,查看配置。
免责声明:我是网络开发新手。我也是问题的作者。
edit:在 /var/log/nginx/HOSTNAME_error.log 中我收到以下错误:
no "ssl_certificate" is defined in server listening on SSL port while SSL handshaking
根据 Steve 的回答、这个问题(参见 link 的评论)和这个 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/ 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')
希望这可以帮助像我这样的人。
我正在尝试使用 nginx、gunicorn 让我的 django 应用程序在 SSL 后工作;都安装在一个可以在内网访问但不能从外部访问的服务器上。这些是我的设置。
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;
}
}
想知道是否有人可以指出正确的解决方案。
为了以防万一,您是否也尝试过设置 ALLOWED_HOSTS
?
此外,正在阅读这篇文章from the docs:
If turning this to True causes infinite redirects, it probably means your site is running behind a proxy and can’t tell which requests are secure and which are not. Your proxy likely sets a header to indicate secure requests; you can correct the problem by finding out what that header is and configuring the SECURE_PROXY_SSL_HEADER setting accordingly.
然后查看 nginx conf 中的内容:
listen 80
...
proxy_set_header X-Forwarded-Protocol $scheme;
您确定 $scheme
是 https
而不是 http
吗?您正在侦听端口 80,而不是端口 443,并且您的 SECURE_PROXY_SSL_HEADER
设置看起来像是在等待 https
可能会转发不安全的 http 请求。
只是猜测,查看配置。
免责声明:我是网络开发新手。我也是问题的作者。
edit:在 /var/log/nginx/HOSTNAME_error.log 中我收到以下错误:
no "ssl_certificate" is defined in server listening on SSL port while SSL handshaking
根据 Steve 的回答、这个问题(参见 link 的评论)和这个 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/ 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')
希望这可以帮助像我这样的人。