[英]Wrong hyperlinks of Django Rest Framework with complex stack using SSL, AWS Load Balancer, Nginx and Gunicorn
I can't find out how to correctly set up nginx
so my hyperlinks in API build by DRF are correct. 我找不到如何正确设置
nginx
因此我在DRF构建的API中的超链接是正确的。
My current configuration for nginx
is: 我当前对
nginx
配置是:
upstream web {
ip_hash;
server web:8000;
}
# portal
server {
listen 8000;
server_name localhost;
location / {
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://web/;
}
}
nginx
is running inside a container exposing port 8000
and maps it into internally running gunicorn (also in a container) also on 8000
. nginx
是在容器内运行暴露端口8000
和地图入内部运行gunicorn(也在容器中)也在8000
。 So when I spin up the whole docker machinery, I can nicely access localhost:8000/api
and links are rendered OK. 因此,当我启动整个docker机械时,我可以很好地访问
localhost:8000/api
并且链接呈现为OK。 Even when I access it using different domain (eg if I set in /etc/hosts
: 127.0.0.1 mytest.com
), the URL and port get passed correctly to the DRF and links are rendered as expect. 即使当我使用其他域访问它时(例如,如果我在
/etc/hosts
: 127.0.0.1 mytest.com
),URL和端口127.0.0.1 mytest.com
正确传递到DRF,并且链接将按预期方式呈现。
But this service must sit behind AWS Load Balancer with certificate using SSL. 但是此服务必须位于具有SSL证书的AWS Load Balancer后面。 Hostname on this LB is set
otherdomain.com
and it redirects traffic to the machine where the above nginx
is run using HTTP on port 8000. Then, when try to access it using https://otherdomain.com/api
, links are rendered as http://otherdomain.com:8000/api/
<- hence wrong scheme
(http instead https) and wrong port (8000 instead of 80/443). 该LB上的主机名设置为
otherdomain.com
,它将流量重定向到使用端口8000上的HTTP在上面运行nginx
的计算机。然后,当尝试使用https://otherdomain.com/api
访问它时,链接呈现为http://otherdomain.com:8000/api/
<-因此使用了错误的scheme
(用HTTP代替https)和错误的端口(用8000代替了80/443)。 It make sense, since nginx
doesn't know anything about the original request coming to load balancer... 这是有道理的,因为
nginx
对到达负载均衡器的原始请求一无所知...
None of the ideas I could think of sounds correct. 我无法想到的任何想法听起来都是正确的。 Would greatly appreciate any help.
将不胜感激任何帮助。 I am willing to change the infrastructure of course.
我当然愿意改变基础架构。
Any idea how can this be solved? 知道如何解决吗?
Add to your settings.py
. 添加到您的
settings.py
。
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')
SECURE_SSL_REDIRECT = not DEBUG
Edit by kotrfa: relevant part of documentation . 由kotrfa编辑: 文档的相关部分 。 I didn't want to add the second line, so it was still possible to access the server directly without HTTPS, eg when testing on localhost.
我不想添加第二行,因此仍然可以在没有HTTPS的情况下直接访问服务器,例如在localhost上进行测试时。 For that, I had to set up two different servers in
nginx
- one with hardcoded Host my.domain.org
on the same port coming from load balancer (eg 7779) and then a second with Host $host:$port
on 7778 so it could be accessed directly behind VPN or on localhost and links still works :-) . 为此,我必须在
nginx
设置两台不同的服务器-一台在负载均衡器(例如7779)来自同一端口上的硬编码Host my.domain.org
,然后一台在7778上使用Host $host:$port
可以直接在VPN后面或在localhost上访问,并且链接仍然有效:-)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.