在内部服务器错误时尝试向管理员发送电子邮件时,Django 没有正确启动 TLS
Django does not properly STARTTLS when attempting to email the admins upon internal server error
我有一个很奇怪的问题。当发生内部服务器错误时,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:<noreply@hydroscope.gr> 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.'.#.....).%.....g.@.3.2.............E.D.........=.5.<./
[practically nothing readable from this point on]
我发现了问题。
运行 系统 ./manage.py shell
和 运行 通过网络服务器的区别在于后者使用 gevent
。该系统是 运行 Debian 的 gevent
1.0.1,它在 SSL 代码中有一个 bug。这在 Django 启动 TLS 时引发了异常。
Django 没有在错误处立即停止,而是假装错误没有发生并继续尝试发送电子邮件,这导致了嗅探中显示的奇怪行为。这是一个Django bug.
正如 Antonis 在他的回答中提到的,这是一个 Django 错误。就我而言,我只是选择了一个接受 TSL 或不接受加密的 SMTP 服务器。您几乎可以在便宜的共享托管计划或专门的 SMTP 服务提供商处托管的所有电子邮件中找到它。
我有一个很奇怪的问题。当发生内部服务器错误时,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:<noreply@hydroscope.gr> 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.'.#.....).%.....g.@.3.2.............E.D.........=.5.<./
[practically nothing readable from this point on]
我发现了问题。
运行 系统 ./manage.py shell
和 运行 通过网络服务器的区别在于后者使用 gevent
。该系统是 运行 Debian 的 gevent
1.0.1,它在 SSL 代码中有一个 bug。这在 Django 启动 TLS 时引发了异常。
Django 没有在错误处立即停止,而是假装错误没有发生并继续尝试发送电子邮件,这导致了嗅探中显示的奇怪行为。这是一个Django bug.
正如 Antonis 在他的回答中提到的,这是一个 Django 错误。就我而言,我只是选择了一个接受 TSL 或不接受加密的 SMTP 服务器。您几乎可以在便宜的共享托管计划或专门的 SMTP 服务提供商处托管的所有电子邮件中找到它。