在Django中排查并升级AWS SES SMTP的TLS版本至1.2
解决AWS SES TLS 1.0/1.1升级及Django项目TLS版本日志问题
一、在日志中打印SMTP连接的TLS版本
Django默认的SMTPEmailBackend不会记录TLS版本,需要自定义后端继承它,在建立连接后获取并记录TLS版本:
- 在你的Django项目中创建一个
backends.py文件(比如放在某个app下,如myapp/backends.py),添加以下代码:
import logging from django.core.mail.backends.smtp import EmailBackend from ssl import SSLSocket logger = logging.getLogger(__name__) class TLSLoggingEmailBackend(EmailBackend): def _get_tls_version(self, sock): if isinstance(sock, SSLSocket): return sock.version() return "Unknown TLS version" def open(self): connection = super().open() if connection: tls_version = self._get_tls_version(connection.sock) logger.info(f"SES SMTP Connection - TLS Version: {tls_version}") return connection
- 修改项目
settings.py中的邮件后端配置:
EMAIL_BACKEND = 'myapp.backends.TLSLoggingEmailBackend'
之后项目发送邮件时,日志中会输出对应的TLS版本,通过日志可以定位到具体哪个项目仍在使用旧版本。
二、强制Django SMTP使用TLS 1.2及以上版本
通过配置自定义SSL上下文,限制仅使用TLS 1.2+:
在settings.py中添加以下配置:
import ssl # 创建默认SSL上下文并禁用TLS 1.0/1.1 EMAIL_SSL_CONTEXT = ssl.create_default_context() EMAIL_SSL_CONTEXT.options |= ssl.OP_NO_TLSv1 EMAIL_SSL_CONTEXT.options |= ssl.OP_NO_TLSv1_1
该配置会在调用starttls时生效(对应你的EMAIL_USE_TLS = True配置),强制SMTP连接仅使用TLS 1.2或更高版本。
三、验证当前环境支持情况
1. 验证服务器OpenSSL支持TLS 1.2
在服务器终端执行以下命令,测试与AWS SES端点的TLS 1.2连接:
openssl s_client -connect <你的AWS SES SMTP端点>:587 -starttls smtp -tls1_2
如果输出中包含Protocol : TLSv1.2且连接成功,说明OpenSSL支持TLS 1.2(你的OpenSSL 1.0.1f版本本身已支持TLS 1.2)。
2. 验证Python SSL模块支持
在项目的虚拟环境中执行Python命令:
import ssl print(ssl.OPENSSL_VERSION) # 检查是否存在禁用旧TLS版本的常量 print(hasattr(ssl, 'OP_NO_TLSv1')) print(hasattr(ssl, 'OP_NO_TLSv1_1'))
若输出为True,说明Python SSL模块支持禁用TLS 1.0/1.1。
四、注意事项
- 先在预发布环境测试配置变更,确认邮件发送正常且日志中显示TLS版本为1.2+后,再推广到生产环境。
- 若部分项目仍使用旧版本,检查是否有硬编码的SMTP配置未使用全局settings,或虚拟环境依赖版本不一致。
内容的提问来源于stack exchange,提问作者Fahad Hussain
相关产品推荐
相关产品推荐

