当由于内部服务器错误而尝试向管理员发送电子邮件时,Django 无法正确启动TLS

标签 django smtp smtp-auth starttls

我有一个非常奇怪的问题。当发生内部服务器错误时,Django 1.6 尝试向管理员发送电子邮件,显然它同意邮件服务器使用 TLS,但随后无法使用它。这是嗅探到的流量:

T 2a00:1450:400c:c0c::6d:587 -> 2001:648:2ffc:1014:a800:ff:fe6b:e499:49271 [AP]
  220 smtp.gmail.com ESMTP lh1sm2677557wjb.20 - gsmtp..                      
##
T 2001:648:2ffc:1014:a800:ff:fe6b:e499:49271 -> 2a00:1450:400c:c0c::6d:587 [AP]
  ehlo peneios.cressendo.org..                                               
##
T 2a00:1450:400c:c0c::6d:587 -> 2001:648:2ffc:1014:a800:ff:fe6b:e499:49271 [AP]
  250-smtp.gmail.com at your service, [2001:648:2ffc:1014:a800:ff:fe6b:e499].
  .250-SIZE 35882577..250-8BITMIME..250-STARTTLS..250-ENHANCEDSTATUSCODES..25
  0-PIPELINING..250-CHUNKING..250 SMTPUTF8..                                 
#
T 2001:648:2ffc:1014:a800:ff:fe6b:e499:49271 -> 2a00:1450:400c:c0c::6d:587 [AP]
  STARTTLS..                                                                 
#
T 2a00:1450:400c:c0c::6d:587 -> 2001:648:2ffc:1014:a800:ff:fe6b:e499:49271 [AP]
  220 2.0.0 Ready to start TLS..                                             
#
T 2001:648:2ffc:1014:a800:ff:fe6b:e499:49271 -> 2a00:1450:400c:c0c::6d:587 [AP]
  mail FROM:<<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0b6564796e7b67724b63726f79647868647b6e256c79" rel="noreferrer noopener nofollow">[email protected]</a>> size=6578..                              
#
T 2a00:1450:400c:c0c::6d:587 -> 2001:648:2ffc:1014:a800:ff:fe6b:e499:49271 [AP]
  ......F                              

如您所见,虽然邮件服务器同意启动 TLS,但 Django 随后发送了一条未加密的 mail FROM: 指令。

但是如果我使用 ./manage.py shell 连接到 Django 并运行:

from django.core.mail import mail_admins
mail_admins('hello', 'hello world')

电子邮件发送正确:

T 2a00:1450:400c:c09::6c:587 -> 2001:648:2ffc:1014:a800:ff:fe6b:e499:53565 [AP]
  220 smtp.gmail.com ESMTP i2sm2684051wjx.42 - gsmtp..                       
##
T 2001:648:2ffc:1014:a800:ff:fe6b:e499:53565 -> 2a00:1450:400c:c09::6c:587 [AP]
  ehlo peneios.cressendo.org..                                               
##
T 2a00:1450:400c:c09::6c:587 -> 2001:648:2ffc:1014:a800:ff:fe6b:e499:53565 [AP]
  250-smtp.gmail.com at your service, [2001:648:2ffc:1014:a800:ff:fe6b:e499].
  .250-SIZE 35882577..250-8BITMIME..250-STARTTLS..250-ENHANCEDSTATUSCODES..25
  0-PIPELINING..250-CHUNKING..250 SMTPUTF8..                                 
#
T 2001:648:2ffc:1014:a800:ff:fe6b:e499:53565 -> 2a00:1450:400c:c09::6c:587 [AP]
  STARTTLS..                                                                 
#
T 2a00:1450:400c:c09::6c:587 -> 2001:648:2ffc:1014:a800:ff:fe6b:e499:53565 [AP]
  220 2.0.0 Ready to start TLS..                                             
#
T 2001:648:2ffc:1014:a800:ff:fe6b:e499:53565 -> 2a00:1450:400c:c09::6c:587 [AP]
  ...........z/x....%....y.F.F..i..8.._w...S...z.0.,.2.../.+.1.-.........(.$.
  ....*.&.....k.j.9.8.'.#.....).%<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="200e0e0e0e0e470e600e130e120e0e0e0e0e0e0e0e0e0e0e0e0e650e64" rel="noreferrer noopener nofollow">[email protected]</a>.........=.5.<./
[practically nothing readable from this point on]

最佳答案

我发现了问题。

使用 ./manage.py shell 运行系统与通过 Web 服务器运行系统之间的区别在于,后者使用的是 gevent。该系统运行的是 Debian 的 gevent 1.0.1,它有一个 bug在 SSL 代码中。这在 Django 启动 TLS 时引发了异常。

Django 没有在错误处立即停止,而是假装错误没有发生并继续尝试发送电子邮件,这导致了嗅探中显示的奇怪行为。这是Django bug .

关于当由于内部服务器错误而尝试向管理员发送电子邮件时,Django 无法正确启动TLS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35315397/

相关文章:

django - 有没有办法更改 drf-spectaulous 中序列化器自动生成的架构名称

python - 如何覆盖 Django 中 ModelForm 的 'type' 属性?

python - 如何使用 2 因素身份验证从 python 发送电子邮件?

smtp - Gmail 使用什么机制进行用户身份验证?

python - 为什么 SendGrid 允许我从任何地址发送电子邮件?

升级到 1.6.5 后的 Django 错误

django - 具有共享代码库和数据库的多个 Django 站点

c# - SMTP 服务器需要安全连接或客户端未通过身份验证。服务器响应为 : 5. 5.1 是否需要身份验证?

python - 如何实现一个可以在 linux 中使用 exchange server host(outbound.company.com) 发送电子邮件的程序

smtp - 通过 Gmail SMTP 发送电子邮件时出错 - "Please log in via your web browser and then try again. 534-5.7.14"