如何解决与 smtpd 相关的 TLS 错误?

如何解决与 smtpd 相关的 TLS 错误?

我在日志中发现以下内容:

sssd_kcm[425899]: Starting up
postfix/submission/smtpd[425910]: initializing the server-side TLS engine
postfix/submission/smtpd[425910]: connect from unknown[::1]
postfix/submission/smtpd[425910]: warning: connect to Milter service unix:/run/spamass-milter/spamass-milter.sock: No such file or directory
postfix/submission/smtpd[425910]: setting up TLS connection from unknown[::1]
postfix/submission/smtpd[425910]: unknown[::1]: TLS cipher list "aNULL:-aNULL:HIGH:MEDIUM:+RC4:@STRENGTH"
postfix/submission/smtpd[425910]: SSL_accept:before SSL initialization
postfix/submission/smtpd[425910]: SSL_accept:before SSL initialization
postfix/submission/smtpd[425910]: SSL_accept:SSLv3/TLS read client hello
postfix/submission/smtpd[425910]: SSL_accept:SSLv3/TLS write server hello
postfix/submission/smtpd[425910]: SSL_accept:SSLv3/TLS write change cipher spec
postfix/submission/smtpd[425910]: SSL_accept:TLSv1.3 write encrypted extensions
postfix/submission/smtpd[425910]: SSL_accept:SSLv3/TLS write certificate
postfix/submission/smtpd[425910]: SSL_accept:TLSv1.3 write server certificate verify
postfix/submission/smtpd[425910]: SSL_accept:SSLv3/TLS write finished
postfix/submission/smtpd[425910]: SSL_accept:TLSv1.3 early data
postfix/submission/smtpd[425910]: SSL3 alert read:fatal:bad certificate
postfix/submission/smtpd[425910]: SSL_accept:error in error
postfix/submission/smtpd[425910]: SSL_accept error from unknown[::1]: -1
postfix/submission/smtpd[425910]: warning: TLS library problem: error:0A000412:SSL routines::sslv3 alert bad certificate:ssl/record/rec_layer_s3.c:1586:SSL alert number 42:
postfix/submission/smtpd[425910]: lost connection after STARTTLS from unknown[::1]
postfix/submission/smtpd[425910]: disconnect from unknown[::1] ehlo=1 starttls=0/1 commands=1/2

每当用户按下用户身份验证表单上的“密码重置”按钮时,这两行就会出现。目前托管在 VPS 上的所有 Django 项目都会发生这种情况。因此,服务器不会发送启动重置的电子邮件。相反,用户在浏览器上看到“服务器错误 (500)”。这种现象是新现象。这些页面几个月前就可以工作了。

日志条目似乎表明证书是错误的。我已更新该服务器上的所有证书以尝试解决该问题,但问题仍然存在。请注意,通过远程和本地客户端提交邮件工作正常。

我希望得到有关如何补救这种情况的指导。

# 会议后 | grep 证书 | grep SMTP

smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
smtp_tls_CApath = /etc/pki/tls/certs
smtp_tls_cert_file =
smtp_tls_dcert_file =
smtp_tls_dkey_file = $smtp_tls_dcert_file
smtp_tls_eccert_file =
smtp_tls_eckey_file = $smtp_tls_eccert_file
smtp_tls_fingerprint_cert_match =
smtp_tls_key_file = $smtp_tls_cert_file
smtp_tls_scert_verifydepth = 9
smtp_tls_secure_cert_match = nexthop, dot-nexthop
smtp_tls_verify_cert_match = hostname
smtpd_tls_ask_ccert = no
smtpd_tls_ccert_verifydepth = 9
smtpd_tls_cert_file = /etc/letsencrypt/live/site.com/fullchain.pem
smtpd_tls_dcert_file =
smtpd_tls_dkey_file = $smtpd_tls_dcert_file
smtpd_tls_eccert_file =
smtpd_tls_eckey_file = $smtpd_tls_eccert_file
smtpd_tls_req_ccert = no
tlsproxy_client_cert_file = $smtp_tls_cert_file
tlsproxy_client_dcert_file = $smtp_tls_dcert_file
tlsproxy_client_eccert_file = $smtp_tls_eccert_file
tlsproxy_client_scert_verifydepth = $smtp_tls_scert_verifydepth
tlsproxy_tls_ask_ccert = $smtpd_tls_ask_ccert
tlsproxy_tls_ccert_verifydepth = $smtpd_tls_ccert_verifydepth
tlsproxy_tls_cert_file = $smtpd_tls_cert_file
tlsproxy_tls_dcert_file = $smtpd_tls_dcert_file
tlsproxy_tls_eccert_file = $smtpd_tls_eccert_file
tlsproxy_tls_req_ccert = $smtpd_tls_req_ccert

答案1

简洁版本: 我一直很傻。

长版: 问题的根源就在我眼皮底下。我在 Django project/settings.py 文件中进行了以下分配:

EMAIL_HOST = "localhost"

出于发展目的,这是可以理解的。我忘记使该值适应生产环境。奇怪的是,这确实有效了一段时间。我没有意识到分配是导致 TLS 握手失败的原因,直到我在相关的 Django shell 中运行以下脚本:

from django.core.mail import send_mail

send_mail(
    "Test Subject",
    "Mr Elephant is tusking the microphone",
    "[email protected]",
    ["[email protected]"],
    fail_silently=False,
)

输出:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/srv/project/venv/lib64/python3.11/site-packages/django/core/mail/__init__.py", line 87, in send_mail
    return mail.send()
           ^^^^^^^^^^^
  File "/srv/project/venv/lib64/python3.11/site-packages/django/core/mail/message.py", line 298, in send
    return self.get_connection(fail_silently).send_messages([self])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/project/venv/lib64/python3.11/site-packages/django/core/mail/backends/smtp.py", line 127, in send_messages
    new_conn_created = self.open()
                       ^^^^^^^^^^^
  File "/srv/project/venv/lib64/python3.11/site-packages/django/core/mail/backends/smtp.py", line 92, in open
    self.connection.starttls(context=self.ssl_context)
  File "/usr/lib64/python3.11/smtplib.py", line 790, in starttls
    self.sock = context.wrap_socket(self.sock,
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/ssl.py", line 517, in wrap_socket
    return self.sslsocket_class._create(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/ssl.py", line 1108, in _create
    self.do_handshake()
  File "/usr/lib64/python3.11/ssl.py", line 1379, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Hostname mismatch, certificate is not valid for 'localhost'. (_ssl.c:1006)

最后一行为我做到了。果然,这触发了日志中的确切条目。我很抱歉!

修复:

EMAIL_HOST = "mail.servername.com"

相关内容