最近,我将django api从2.2更新到3.1。我更新了dockerfile和相关的bash文件,比如django-炊具做了https://github.com/pydanny/cookiecutter-django/commit/b22045bcd4ebf563ccdcf226fb389a6bb71e2654#diff-1872e6a6f0bbcb27f2eda185ac89eed05eb7a402b298e58bcbef29bf039c2c13。
升级大部分进展顺利,除了现在的生产,我们不能发送电子邮件。我在生产中运行了一个最小的管理命令来测试电子邮件设置。
from django.conf import settings
from django.core.mail import send_mail
from django.core.management.base import BaseCommand
class Command(BaseCommand):
"""
Sends an email to the provided addresses.
"""
help = "Sends an email to the provided addresses."
def add_arguments(self, parser):
parser.add_argument("emails", nargs="+")
def handle(self, *args, **options):
self.stdout.write(f"send_email from: {settings.EMAIL_FROM_FIELD}")
for email in options["emails"]:
try:
send_mail(
"expert-system test email",
"a simple email",
settings.EMAIL_FROM_FIELD,
[email],
)
except BaseException as e:
self.stdout.write(f"Problem sending email: {e}")这会返回
$ python manage.py send_email harry@test.com
send_email from: test@test.com
Problem sending email: EOF occurred in violation of protocol (_ssl.c:1125)另一个堆栈溢出建议测试是否支持tls 1.1。
$ python -c "from urllib.request import urlopen ;
print(urlopen('https://www.howsmyssl.com/a/check').read())"
b'{"given_cipher_suites":["TLS_AES_256_GCM_SHA384","TLS_CHACHA20_POLY1305_SHA256","TLS_AES_128_GCM_SHA256","TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384","TLS_DHE_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256","TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256","TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256","TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256","TLS_DHE_RSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384","TLS_DHE_RSA_WITH_AES_256_CBC_SHA256","TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256","TLS_DHE_RSA_WITH_AES_128_CBC_SHA256","TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA","TLS_DHE_RSA_WITH_AES_256_CBC_SHA","TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA","TLS_DHE_RSA_WITH_AES_128_CBC_SHA","TLS_RSA_WITH_AES_256_GCM_SHA384","TLS_RSA_WITH_AES_128_GCM_SHA256","TLS_RSA_WITH_AES_256_CBC_SHA256","TLS_RSA_WITH_AES_128_CBC_SHA256","TLS_RSA_WITH_AES_256_CBC_SHA","TLS_RSA_WITH_AES_128_CBC_SHA","TLS_EMPTY_RENEGOTIATION_INFO_SCSV"],"ephemeral_keys_supported":true,"session_ticket_supported":true,"tls_compression_supported":false,"unknown_cipher_suite_supported":false,"beast_vuln":false,"able_to_detect_n_minus_one_splitting":false,"insecure_cipher_suites":{},"tls_version":"TLS 1.3","rating":"Probably Okay"}'如何在制作时发送电子邮件?
发布于 2021-04-03 23:50:39
因此,简而言之,您的邮件服务器很可能只支持TL1.1,甚至只支持TLS1.0,而slim buster映像不再支持这些协议。
回到3.7-阿尔卑斯(这是已知的工作组合)或一个旧的ubuntu/debian版本,仍然支持这些协议,将允许您再次发送邮件。
那么您应该升级您的邮件服务器,因为TLS 1.0和TLS 1.1都应该在很久以前就已经失效了。
编辑:
测试邮件服务器的另一种方法是使用openssl的s_client命令:
openssl s_client -no_tls1 -no_tls1_1 -no_tls1_2 -connect your.mail.host:port这很可能会失败。然后移除-no_tls标志,直到它开始工作,并且您知道它支持的最高协议。
注意:只有在支持TLSv1.3
的openssl版本上才支持 -no_tls1_2
发布于 2021-04-05 17:17:02
修复方法是使用最初工作的os python:3.7-alpine,它似乎能够发送电子邮件,但是smtp服务器需要它(仍然不确定它强制的tls版本,但我假设它的tls 1.2)。
还想补充一下我们尝试使用python的原因:3.8SIM-buster是因为炊具使用它,这是由https://pythonspeed.com/articles/base-image-python-docker-images/推荐的,而最新版本的加密模块(3.4+ https://cryptography.io/en/latest/changelog.html#v3-4)推荐使用现代版本的pip (否则你必须安装铁锈才能编译密码)。django-allauth (通过pyjwt)需要加密模块。
为了使用django-allauth的现代版本(我认为django 3.1需要它),我将密码模块固定在最新的预锈版上。
django-allauth==0.44.0 # https://github.com/pennersr/django-allauth
cryptography==3.3.2 # https://github.com/pyca/cryptographyhttps://stackoverflow.com/questions/66924714
复制相似问题