同一服务器上Django与MinIO的HTTPS配置问题求助
问题:Django连接MinIO HTTPS时出现SSL证书验证失败错误
错误信息
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='subdomain.domain.org', port=9000): Max retries exceeded with url: /django-backend-dev-public (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1006)')))
环境背景
- 服务器系统:Ubuntu 22.04 LTS
- MinIO版本:2024-08-03T04-33-23Z
- Django版本:5.0.6
- HTTP连接时Django可正常上传文件至MinIO;切换为HTTPS后MinIO WebUI可正常访问,但Django触发上述错误
- MinIO已配置
/opt/minio/certs目录下的public.crt与private.key证书
Django settings.py相关配置
ALLOWED_HOSTS = [ 'localhost', '127.0.0.1', 'subdomain.domain.org' ] CSRF_TRUSTED_ORIGINS = [ 'https://subdomain.domain.org', 'https://127.0.0.1', 'https://localhost' ] CSRF_ALLOWED_ORIGINS = ["https://subdomain.domain.org", "https://localhost"] CORS_ORIGINS_WHITELIST = ["https://subdomain.domain.org", "https://localhost"] INTERNAL_IPS = ['127.0.0.1', 'localhost', 'subdomain.domain.org'] MINIO_CONSISTENCY_CHECK_ON_START = True MINIO_ENDPOINT = 'subdomain.domain.org:9000' MINIO_EXTERNAL_ENDPOINT = 'subdomain.domain.org:9000' MINIO_EXTERNAL_ENDPOINT_USE_HTTPS = True MINIO_REGION = 'eu-west-1' # Default is set to None, current is Ireland MINIO_ACCESS_KEY = 'XXXXXX' MINIO_SECRET_KEY = 'YYYYY' MINIO_USE_HTTPS = True MINIO_URL_EXPIRY_HOURS = timedelta( days=1) # Default is 7 days (longest) if not defined MINIO_PRIVATE_BUCKETS = ['django-backend-dev-private', ] MINIO_PUBLIC_BUCKETS = ['django-backend-dev-public', ] MINIO_POLICY_HOOKS: List[Tuple[str, dict]] = [] MINIO_MEDIA_FILES_BUCKET = 'bridge-media-files-bucket' MINIO_PRIVATE_BUCKETS.append(MINIO_MEDIA_FILES_BUCKET) MINIO_STATIC_FILES_BUCKET = 'bridge-static-files-bucket' MINIO_PRIVATE_BUCKETS.append(MINIO_STATIC_FILES_BUCKET) MINIO_BUCKET_CHECK_ON_SAVE = True # SSL SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') SECURE_SSL_REDIRECT = True SECURE_HSTS_SECONDS = 31536000 # 1 year SECURE_HSTS_INCLUDE_SUBDOMAINS = True SECURE_HSTS_PRELOAD = True SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True
错误原因分析
- 证书信任缺失:MinIO使用的自签名/私有CA颁发证书未被Django运行的Python环境信任。浏览器能正常访问是因为手动信任了证书,但Python默认依赖系统CA证书库,若该库未包含MinIO证书的根CA,就会触发验证失败。
- 证书链不完整:
public.crt可能仅包含服务器证书,缺少中间CA证书,导致Python无法完整追溯到信任的根证书。 - Python CA库未同步系统信任:即使证书已导入系统,Python虚拟环境可能未读取到更新后的CA证书。
解决方法
1. 将证书导入系统信任库
执行以下命令把MinIO证书添加到系统级CA信任:
sudo cp /opt/minio/certs/public.crt /usr/local/share/ca-certificates/minio.crt sudo update-ca-certificates
此操作会更新系统CA证书库,Python默认会使用该库进行证书验证。
2. 指定Python使用的CA证书路径
若系统导入后仍未生效,可通过环境变量强制Python使用MinIO的证书:
启动Django时添加环境变量:
REQUESTS_CA_BUNDLE=/opt/minio/certs/public.crt python manage.py runserver
生产环境可在启动脚本中配置该环境变量。
3. 检查并补全证书链
如果MinIO的证书由私有CA颁发,需将服务器证书和中间CA证书合并到public.crt中,顺序为:服务器证书在前,中间CA证书在后。合并命令示例:
cat server.crt intermediate.crt > /opt/minio/certs/public.crt
替换server.crt和intermediate.crt为实际文件路径,之后重启MinIO服务。
4. 临时跳过验证(仅测试场景)
生产环境禁止使用,若需快速确认问题根源,可在Django settings中添加:
MINIO_VERIFY_SSL = False
验证通过后务必移除该配置,恢复证书验证以保证安全性。
内容的提问来源于stack exchange,提问作者Timothy Tuti
相关产品推荐
相关产品推荐

