I know this topic is already some days old - but the following might be of interest for others who have to fix the same issue.
But first of all thx @JavaNoScript - the answer nearly fixed it for us.
We did not want to switch off verification - but needed to get a solution for sending mails using self-signed certificates validated against our internal root CA.
Therefore the Django EmailBackend had to be modified for using the internal trust store (in our case: /etc/ssl/certs/).
See also python ssl context documentation.
Here the modified script from above:
import ssl
from django.core.mail.backends.smtp import EmailBackend as SMTPBackend
from django.utils.functional import cached_property
from django.conf import settings as django_settings
class EmailBackend(SMTPBackend):
@cached_property
def ssl_context(self):
if self.ssl_certfile or self.ssl_keyfile:
ssl_context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT)
# set verify location:
if hasattr(django_settings, 'CA_PATH') and django_settings.CA_PATH is not None:
ssl_context.load_verify_locations(capath=django_settings.CA_PATH)
ssl_context.load_cert_chain(self.ssl_certfile, self.ssl_keyfile)
return ssl_context
else:
ssl_context = ssl.create_default_context()
return ssl_context
The other steps are pretty similar to the ones mentioned above:
Use the custom backend rather than the standard one
# settings.py
# old value (was not included in our settings.py before):
# EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_BACKEND = 'backend.email.EmailBackend'
And define the settings variables for sending certified mails:
# settings.py
EMAIL_SSL_CERTFILE = "/path/to/CERTFILE.crt"
EMAIL_SSL_KEYFILE = "/path/to/private/KEYFILE.key" # make sure it is accessible by the executing user
CA_PATH = '/path/to/cert/folder/' # e.g. '/etc/ssl/certs/' on ubuntu linux - this one is new
Took us a while to figure this out.
I hope it helps some of you (although there might be more solid variable testing).