简体   繁体   English

Django 落后于 NGINX 反向代理和 AWS Application Load Balancer 未在 HTTP_X_FORWARDED_PROTO 中从客户端转发 HTTPS

[英]Django behind NGINX reverse proxy and AWS Application Load Balancer doesn't get HTTPS forwarded from client in HTTP_X_FORWARDED_PROTO

I'm running Django on Gunicorn behind a NGINX reverse proxy, and an AWS Application Load Balancer.我在 NGINX 反向代理和 AWS 应用程序负载均衡器后面的 Gunicorn 上运行 Django。 The ALB has 2 listeners. ALB 有 2 个侦听器。 The HTTPS listener forwards to a Target Group in port 80, and the HTTP listener redirects to HTTPS. HTTPS 侦听器转发到端口 80 中的目标组,HTTP 侦听器重定向到 HTTPS。

在此处输入图像描述

The ALB thus connects with an AWS ECS Cluster, which runs a task with 2 containers: one for the Django app, and another for the NGINX that acts as a reverse proxy for the Django app.因此,ALB 与 AWS ECS 集群连接,该集群使用 2 个容器运行任务:一个用于 Django 应用程序,另一个用于 NGINX,充当 Django 应用程序的反向代理。 Here's the configuration for the NGINX reverse proxy:这是 NGINX 反向代理的配置:

upstream django {
    server web:8000;
}

server {
    listen       80;
    listen  [::]:80;

    location / {
        proxy_pass http://django;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_ssl_server_name on;
        proxy_redirect off;
    }
}

This configuration ensures that whenever the client tries to hit the website app using an HTTP request, he gets redirected to HTTPS. And everything works fine with one exception.此配置确保每当客户端尝试使用 HTTP 请求访问网站应用程序时,他都会被重定向到 HTTPS。除了一个例外,一切正常。 In Django, when I run request.is_secure() I'm getting False instead of True as expected.在 Django 中,当我运行request.is_secure()时,我得到的是False而不是预期的True If I run request.build_absolute_uri() , I get http://mywebsite.com and not https://mywebsite.com as expected.如果我运行request.build_absolute_uri() ,我得到http://mywebsite.com而不是预期的https://mywebsite.com

I already tried adding the following lines to settings.py :我已经尝试将以下行添加到settings.py

USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

as explained in the documentation, but it doesn't work.如文档中所述,但它不起作用。 Whenever I inspect request.META (or the raw request.headers ), I'm seeing 'HTTP_X_FORWARDED_PROTO': 'http' (and the equivalent raw 'X-Forwarded-Proto': 'http' ) instead of https as expected.每当我检查request.META (或原始request.headers )时,我都会看到'HTTP_X_FORWARDED_PROTO': 'http' (以及等效的原始'X-Forwarded-Proto': 'http' )而不是预期的https The stack is correctly forwarding 'HTTP_X_FORWARDED_HOST': 'mywebsite.com' from the client, but the scheme is being ignored.堆栈从客户端正确转发'HTTP_X_FORWARDED_HOST': 'mywebsite.com' ,但方案被忽略。

Can anyone help me identify what I'm doing wrong and how to fix it?谁能帮我确定我做错了什么以及如何解决? Thanks谢谢

With a Classic ELB you specify the "instance port" (see the listeners tab) and that controls the protocol that you send downstream to nginx. In that scenario it is common to attach an SSL cert to the 443 port but send HTTP down port 80 to nginx. the port 80 listener also sends HTTP .使用经典 ELB,您可以指定“实例端口”(请参阅侦听器选项卡)并控制您向下游发送到 nginx 的协议。在这种情况下,通常将 SSL 证书附加到 443 端口,但将HTTP发送到端口 80到 nginx。端口 80 侦听器还发送HTTP In that setup, where only HTTP is coming in from the load balancer it is your job to inspect the X-Forwarded-Proto header and perform a permanent redirect to HTTPS .在该设置中,只有HTTP来自负载均衡器,您的工作是检查X-Forwarded-Proto header 并执行永久重定向到HTTPS That's because the classic ELB could not redirect HTTP to HTTPS .那是因为经典的 ELB 无法将HTTP重定向到HTTPS With the Application Load Balancer (ALB) I believe you can redirect HTTP to HTTPS if you want to speak 443 to nginx.使用应用程序负载均衡器 (ALB),如果您想将 443 转至 nginx,我相信您可以将 HTTP 重定向至 HTTPS。

In your specific case it seems like you were only listening on Port 80 so you were probably only sending HTTP from the load balancer.在您的特定情况下,您似乎只在端口 80 上监听,因此您可能只从负载均衡器发送 HTTP。 Check you Instance Port and protocol.检查您的实例端口和协议。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将 http 重定向到 https AWS 应用程序负载均衡器 - Redirect http to https AWS Application Load Balancer 使用 Application Load Balancer 将 http 重定向到 https - Redirect http to https using Application Load Balancer Elastic Beans + Django。使用负载均衡器将 HTTP 切换为 HTTPS - Elastic Beans + Django. Switch HTTP to HTTPS using Load Balancer 在 AWS 应用程序负载均衡器后面添加 x-pack enabled Elasticsearch 由于缺少身份验证导致健康检查失败 - Adding x-pack enabled Elasticsearch behind AWS application load balancer causing health check failure due to missing authentication Google Cloud Load Balancer 中的 HTTP 到 HTTPS 重定向不适用于多个域 - HTTP-to-HTTPS redirect in Google Cloud Load Balancer doesn't work for multiple domains 是否有选项将 http 流量重定向到 aws.network 负载均衡器中的 https - Is there option to redirect http traffic to https in aws network load balancer 负载均衡器无法在 Elastic Beanstalk 中从 HTTP 重定向到 HTTPS - Load Balancer unable to redirect from HTTP to HTTPS in Elastic Beanstalk Ingress 和 AWS 应用程序负载均衡器 - Ingress and AWS Application Load Balancer 从 Load Balancer 后面访问 AWS EC2 Inte.net - AWS EC2 Internet access from behind Load Balancer 将 EC2 弹性负载均衡器从 HTTP 重定向到 HTTPS - Redirecting EC2 Elastic Load Balancer from HTTP to HTTPS
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM