如何动态地将EC2 IP地址添加到Django ALLOWED_HOSTS

tra*_*ash 11 python django amazon-ec2 amazon-web-services

我们最近更改了部署策略以使用AWS自动扩展组.

我们在生产中遇到的一个问题是新创建的EC2.
我们的申请开始返回:

Invalid HTTP_HOST header: 
    <ip_address>. You may need to add <ip_address> to ALLOWED_HOSTS`
Run Code Online (Sandbox Code Playgroud)

因为这些EC2不在原来的Django中ALLOWED_HOSTS.

每个新创建的EC2都必须重新部署是没有意义的; 这与"汽车规模"的意义相矛盾.
此外,出于安全原因,我们不希望使用通配符或IP范围.

我们能做什么?

Pat*_*our 12

您可以通过发出API请求来检索EC2实例元数据

curl http://169.254.169.254/latest/meta-data/
GET http://169.254.169.254/latest/meta-data/
Run Code Online (Sandbox Code Playgroud)

资源

您可以通过进行API调用来获取特定实例的私有IP:

GET http://169.254.169.254/latest/meta-data/local-ipv4
Run Code Online (Sandbox Code Playgroud)

因此,在您的Django设置文件中添加此脚本以"动态"将IP添加到您允许的主机:

import requests
EC2_PRIVATE_IP = None
try:
    EC2_PRIVATE_IP = requests.get(
        'http://169.254.169.254/latest/meta-data/local-ipv4',
        timeout=0.01).text
except requests.exceptions.RequestException:
    pass

if EC2_PRIVATE_IP:
    ALLOWED_HOSTS.append(EC2_PRIVATE_IP)
Run Code Online (Sandbox Code Playgroud)


小智 2

下面的代码片段将找到与您的 EC2 实例关联的公共 IP 地址或弹性 IP 地址,并将其附加到 ALLOWED_HOSTS。

  • 安装 PyCurl

    pip install pycurl
    
    Run Code Online (Sandbox Code Playgroud)
  • 蟒蛇3

    import pycurl
    from io import BytesIO
    
    # Determine Public IP address of EC2 instance
    buffer = BytesIO()
    c = pycurl.Curl()
    c.setopt(c.URL, 'checkip.amazonaws.com')
    c.setopt(c.WRITEDATA, buffer)
    c.perform()
    c.close()
    # Body is a byte string, encoded. Decode it first.
    ALLOWED_HOSTS.append(buffer.getvalue().decode('iso-8859-1').strip())
    
    Run Code Online (Sandbox Code Playgroud)
  • 蟒蛇2

    import pycurl
    from StringIO import StringIO
    
    buffer = StringIO()
    c = pycurl.Curl()
    c.setopt(c.URL, 'checkip.amazonaws.com')
    c.setopt(c.WRITEDATA, buffer)
    c.perform()
    c.close()
    # In Python 2, we can cast the return value to
    # string without knowing the exact encoding.
    ALLOWED_HOSTS.append(str(buffer.getvalue()).strip())
    
    Run Code Online (Sandbox Code Playgroud)