![](/img/trans.png)
[英]HTTP to HTTPS with health link on Elastic Beanstalk using Django
[英]Django and Elastic Beanstalk URL health checks
我有一个Django webapp。 它在Elastic Beanstalk上的Docker中运行。
我想指定一个运行状况检查URL,用于稍微更高级的运行状况检查,而不是“ELB是否可以建立TCP连接”。
完全合理的是,ELB通过使用实例的主机名(例如ec2-127-0-0-1.compute-1.amazonaws.com
)作为Host
头连接到HTTP实例来完成此操作。
Django有ALLOWED_HOSTS
,用于验证传入请求的Host
头。 我通过环境变量将它设置为我的应用程序的外部域。
不出所料,完全合理的是,由于缺少匹配的Host
,Django因此拒绝ELB URL健康检查。
我们不想禁用ALLOWED_HOSTS
因为我们希望能够信任get_host()
。
到目前为止,解决方案似乎是:
ALLOWED_HOSTS
(即健康检查URL) ALLOWED_HOSTS
这些都不是特别令人愉快。 有人可以推荐更好/现有的解决方案吗?
(为避免疑问,我认为这个问题与“禁用ALLOWED_HOSTS
,面向主机上过滤的HTTPD前端”的情况相同 - 我希望健康检查能够点击Django ,而不是前面的HTTPD)
如果ELB运行状况检查使用包含弹性beanstalk域(* .elasticbeanstalk.com或EC2域* .amazonaws.com)的主机头发送其请求,则标准ALLOWED_HOSTS
仍可用于'.amazonaws.com'
的通配符条目'.amazonaws.com'
或'.elasticbeanstalk.com'
。
在我的情况下,我收到标准的ipv4地址作为健康检查主机,因此需要一个不同的解决方案。 如果您根本无法预测主机,并且假设您不能预测主机可能更安全,则需要采取以下路线之一。
您可以使用Apache来处理已批准的主机,而不是将不明确的请求传播到Django。 由于主机头旨在成为接收请求的服务器的主机名,因此此解决方案会更改有效请求的标头以使用预期的站点主机名。 随着弹性魔豆你需要使用配置Apache .ebextensions
描述这里 。 在项目根目录下的.ebextensions
目录下,将以下内容添加到.config文件中。
files:
"/etc/httpd/conf.d/eb_healthcheck.conf":
mode: "000644"
owner: root
group: root
content: |
<If "req('User-Agent') == 'ELB-HealthChecker/1.0' && %{REQUEST_URI} == '/status/'">
RequestHeader set Host "example.com"
</If>
使用您站点的相应域替换/status/
使用您的运行状况检查URL和example.com
。 这告诉Apache检查所有传入请求并使用正在请求相应运行状况检查URL的相应运行状况检查用户代理更改请求上的主机头。
如果您真的不想配置Apache,可以编写自定义中间件来验证运行状况检查。 中间件必须覆盖Django的CommonMiddleware
,它调用HttpRequest
的get_host()
方法来验证请求的主机。 你可以这样做
from django.middleware.common import CommonMiddleware
class CommonOverrideMiddleware(CommonMiddleware):
def process_request(self, request):
if not('HTTP_USER_AGENT' in request.META and request.META['HTTP_USER_AGENT'] == 'ELB-HealthChecker/1.0' and request.get_full_path() == '/status/'):
return super().process_request(request)
这只允许任何健康检查请求跳过主机验证。 然后在settings.py
中用path.CommonOverrideMiddleware
替换django.middleware.common.CommonMiddleware
。
我建议使用Apache配置方法来避免中间件中的任何细节,并完全将Django与主机问题隔离开来。
这是我使用的,它运作良好:
import socket
local_ip = str(socket.gethostbyname(socket.gethostname()))
ALLOWED_HOSTS=[local_ip, '.mydomain.com', 'mydomain.elasticbeanstalk.com' ]
在哪里用你自己的mydomain
和mydomain.elasticbeanstalk.com
替换它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.