添加第二个域名后出现SSL证书验证失败问题求助
问题分析与解决方案
核心问题定位
从报错栈和现象来看,外部请求能正常返回400错误,说明NGINX的SSL证书是有效的,问题出在Docker容器内的Python环境发送邮件时,无法验证邮件服务器的SSL证书,或者容器缺少完整的根CA证书链导致验证失败。该问题在给Certbot添加第二个域名后出现,大概率是容器内的CA证书未同步更新,或邮件服务的证书验证环节受到域名变更的间接影响。
解决方案
方案1:给Docker容器补充完整根CA证书
Python官方镜像默认的CA证书可能不全,通过安装系统CA证书包解决:
- 修改你的Dockerfile,添加以下命令:
# 安装并更新CA证书 RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && update-ca-certificates
- 重新构建Docker镜像,重启容器。
方案2:在Django中指定邮件验证的CA证书路径
如果需要指定Certbot生成的完整证书链,或邮件服务器使用自定义证书:
- 在Django的
settings.py中添加邮件配置:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = '你的邮件服务器地址' EMAIL_PORT = 587 # 或对应邮件服务器的TLS端口 EMAIL_USE_TLS = True # 指定Certbot生成的全链证书路径 EMAIL_SSL_CERTFILE = '/etc/letsencrypt/live/你的主域名/fullchain.pem'
- 在
docker-compose.yml或容器启动命令中,挂载Certbot证书目录到容器内(只读权限即可):
volumes: - /etc/letsencrypt:/etc/letsencrypt:ro
方案3:临时跳过证书验证(仅测试用,禁止生产环境)
若仅用于测试,可临时关闭SSL证书验证:
import ssl from django.conf import settings settings.EMAIL_SSL_CONTEXT = ssl.create_default_context() settings.EMAIL_SSL_CONTEXT.check_hostname = False settings.EMAIL_SSL_CONTEXT.verify_mode = ssl.CERT_NONE
排查验证步骤
- 在Docker容器内执行命令,测试邮件服务器的证书链:
openssl s_client -connect 你的邮件服务器地址:587 -starttls smtp
查看输出中是否有Verify return code: 0 (ok),若不为0则说明邮件服务器证书本身有问题。
2. 检查Certbot生成的fullchain.pem文件,确认包含完整的证书链(根CA、中间CA、域名证书),而非仅域名证书。
3. 同步容器与主机的系统时间,时间偏差过大也会导致证书验证失败:
# 在容器内执行 apt-get install -y ntpdate && ntpdate pool.ntp.org
内容的提问来源于stack exchange,提问作者Sdu_Max
相关产品推荐
相关产品推荐

