Elastic Load Balancer 后面的 Elastic beanstalk 实例的 Django ALLOWED_HOSTS 设置

Posted

技术标签:

【中文标题】Elastic Load Balancer 后面的 Elastic beanstalk 实例的 Django ALLOWED_HOSTS 设置【英文标题】:Django ALLOWED_HOST setting for Elastic beanstalk instance behind Elastic Load Balancer 【发布时间】:2016-03-29 11:41:21 【问题描述】:

问。如何在 Elastic beantalk 实例上设置 django ALLOW_HOSTS 以允许 Elastic Load Balancer IP?

背景

我在 elastic beanstalk 上部署了 django 网站。网站域名被添加到ALLOW_HOSTS,因此django可以正确接受正常的请求。

ALLOWED_HOSTS = ['.mydomain.com']

Elastic Load balancer 直接使用 IP 地址访问 Elastic beanstalk 实例进行健康检查,因此下一行允许进行健康检查:

# add elastic beanstalk instance local ip
aws_ip = requests.get('http://169.254.169.254/latest/meta-data/local-ipv4', timeout=0.1).text
ALLOWED_HOSTS.append(aws_ip)

但我仍然收到无效的 HOST IP 错误,似乎弹性 beantalk 实例是使用弹性负载均衡器公共 IP 访问的。网上有 EC2 部署的解决方案,因为您可以设置 HTTPD 软件在 IP 直接访问它时设置 http HOST 标头。但是我们不能在弹性 beantalk 上配置 apache。那么如何将弹性负载均衡器 IP 添加到ALLOW_HOSTS

【问题讨论】:

【参考方案1】:

没有充分的理由接受定向到您 ELB 的 IP 的流量。对于健康检查,我的首选方法:

import requests
try:
    internal_ip = requests.get('http://instance-data/latest/meta-data/local-ipv4').text
except requests.exceptions.ConnectionError:
    pass
else:
    ALLOWED_HOSTS.append(internal_ip)
del requests
没有复杂的 apache 配置,这取决于您的域 在 dns 上快速失败,无需依赖超时

【讨论】:

对我来说这应该是公认的答案。以简单的方式解决了这个问题,特别是对于软件开发人员。另外,我们可以放心,当 django 引发异常时,ELB 健康检查将捕获。 对不起,我投了反对票,但我错了,请编辑答案以更改我的投票 即使添加了这个,您是否仍然看到 Invalid HTTP_HOST 标头错误?即使在我添加了这个之后,我每小时也会收到数百个 HOST HEADER。【参考方案2】:

我相信最好的方法是配置 Apache 来处理请求主机验证。即使使用 beanstalk,您也应该能够使用 .ebextensions 配置 Apache。

总体思路是检查'ELB-HealthChecker/1.0' User-Agent 的传入请求以及您设置为请求的REQUEST_URI 的运行状况检查URL。这些请求可以使用RequestHeader set Host 命令将其主机标头更改为允许的主机。

如果真的不想配置 Apache,您可以实现自定义中间件来覆盖 Django 的 CommonMiddleware,以允许运行状况检查器请求绕过 Django 的 ALLOWED_HOST 验证。

如果您需要更多关于实施其中一种解决方案的信息,我在 this answer 中进行了更详细的介绍。

【讨论】:

【参考方案3】:

将 EC2 实例的本地 IP 添加到允许的主机对我有用。

settings.py:

import socket

hostname = socket.gethostname()
local_ip = socket.gethostbyname(hostname)

ALLOWED_HOSTS = ['...', local_ip]

【讨论】:

【参考方案4】:

您添加分配给该主机的 IP 列表。 只有 IP 地址没有 http:// 或 /latest/media...

【讨论】:

我用实际代码替换了伪代码......但是这些行只添加了弹性beantalk实例IP,我需要添加弹性负载均衡器的IP beanstalk 实例 上没有安装 django 应用程序吗?如果这是正确的,那么您应该添加的 beanstalk 实例 IP 不是负载均衡器。 ALLOWD_HOSTS 没有指定哪些主机可以连接到您的 Django 应用程序,它具体说明了接受什么 HOST http 标头。当您按域访问 django 时,HOST 标头将具有类似 mydomain.com 的值,当通过 IP 访问时,HOST 标头将具有您正在访问的 IP 作为其值【参考方案5】:

在 settings.py 这是我使用的配置,它对我很有效(至少对于 DEV):

# AWS config for ElasticBeanstalk
ALLOWED_HOSTS = [
    '127.0.0.1',
    'localhost',
    '.compute-1.amazonaws.com', # allows viewing of instances directly
    '.elasticbeanstalk.com' 
]

希望对你有帮助。

【讨论】:

在执行 eb deploy 之后,settings.py 更改为 ALLOWED_HOSTS = ['.elasticbeanstalk.com' ] 。这有时会给我 ALLOWED HOSTS 错误。我的意思是错误不一致。有什么想法吗? 这完全不安全......如果我尝试在单个 EC2 中使用亚马逊域来破解你,我会成功

以上是关于Elastic Load Balancer 后面的 Elastic beanstalk 实例的 Django ALLOWED_HOSTS 设置的主要内容,如果未能解决你的问题,请参考以下文章

在 AWS Elastic Load Balancer 后面使用 Primus.io (websockets)

如何为 Elastic Load Balancer 配置自动超时?

Amazon Codedeploy + Elastic Load Balancer - Windows 支持

Cloudformation 协助 Elastic Beanstalk 和 Application Load Balancer

AWS - Elastic Load Balancing 是不是真的阻止了 LOAD BALANCER 故障转移?

使用 Tomcat 的 Elastic Load Balancer 出现 504 错误