Django 生产环境 ALLOWED_HOSTS 怎么配置域名白名单?

文章导读
生产环境下,Django 必须关闭调试模式并明确填写允许访问的域名列表,否则服务会直接拒绝请求。
📋 目录
  1. 核心配置方法
  2. 反向代理配置参考
  3. 验证与日志排查
  4. 常见风险与坑
  5. 参考来源
A A

生产环境下,Django 必须关闭调试模式并明确填写允许访问的域名列表,否则服务会直接拒绝请求。

核心结论:这是 Django 安全机制的强制要求,配置错误会导致网站无法访问或存在安全风险。

  • 适用场景:正式部署、关闭 DEBUG 后的生产环境
  • 关键动作:核对实际访问域名、IP 及负载均衡器地址
  • 验证方法:通过不同 Host 头请求确认拦截策略生效

核心配置方法

找到项目中的 settings.py,定位到 ALLOWED_HOSTS 变量。支持精确匹配和子域名通配。

ALLOWED_HOSTS = ['example.com', 'www.example.com']

支持子域名通配配置:

Django 生产环境 ALLOWED_HOSTS 怎么配置域名白名单?
ALLOWED_HOSTS = ['.example.com']  # 匹配 example.com 及所有子域名

最佳实践:生产环境建议使用环境变量管理敏感配置,避免硬编码。

import os
ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', '').split(',')
# 环境变量示例:ALLOWED_HOSTS=example.com,www.example.com

反向代理配置参考

如果前方有 Nginx 等代理,需确保 Django 能获取到真实的 Host。需在 Nginx 中配置 proxy_set_header 传递 Host 头。

server {
    listen 80;
    server_name example.com;
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

配置后重启 Nginx 及 Django 服务(WSGI/ASGI)生效。

验证与日志排查

使用 curl 命令模拟请求。正常域名应返回 200 状态码,未授权的 Host 应返回 400 状态码。

Django 生产环境 ALLOWED_HOSTS 怎么配置域名白名单?
curl -H "Host: evil.com" http://your-server-ip/

查看 Django 日志,确认是否有 Invalid HTTP_HOST header 相关的报错记录。

常见风险与坑

1. 通配符滥用:生产环境严禁使用通配符 *,这会禁用主机头验证,存在安全风险,即使 DEBUG 为 False 也不建议使用。

2. 忽略子域名:www 和非 www 是两个不同的 Host,需分别添加或使用前缀点号。

Django 生产环境 ALLOWED_HOSTS 怎么配置域名白名单?

3. IPv6 地址格式:IPv6 地址需要包含方括号,如 [::1]。

4. 负载均衡健康检查:负载均衡器的健康检查请求可能使用 IP 或特定 Host,需将其加入白名单。

参考来源

Django Documentation: ALLOWED_HOSTS | Settings reference (https://docs.djangoproject.com/en/stable/ref/settings/#allowed-hosts)