![](/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.