Sentry: Missing support for SMTP with SSL

Created on 1 Oct 2016  ·  32Comments  ·  Source: getsentry/sentry

See forum topic.

It turns out Sentry only supports TLS (and not SSL) for outgoing email. This is not immediately apparent (or documented). Settings like the ones below (though correct in Django) don't actually work in Sentry:

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'mail.privateemail.com'
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = '***'
EMAIL_PORT = 465
EMAIL_USE_SSL = True
EMAIL_USE_TLS = False
SERVER_EMAIL = EMAIL_HOST_USER

When I try to send a test email I get this:

Connection unexpectedly closed: timed out

Most helpful comment

I don't know why by for Yandex i use 465 port and SSL in postclient and the only config that worked for me on Sentry 9 is :

mail.backend: 'smtp'  # Use dummy if you want to disable email entirely
mail.host: 'smtp.yandex.ru'
mail.port: 25
mail.username: '[email protected]'
mail.password: 'mypassword'
mail.use-tls: true
mail.from: '[email protected]'

All 32 comments

Looks like SSL support was introduced in Django 1.7, but we're stuck on Django 1.6 for the time being, so this might be case for a while, unfortunately.

Oh, TIL. I was assuming this would be an easy fix that I somehow overlooked when porting this stuff to use options. :(

I was assuming this would be an easy fix that I somehow overlooked when porting this stuff to use options.

Me too — I was halfway through implementing it, then looked at the Django source for what the SSL constructor parameter to the email backend was… and realized it wasn't there. 😕

Update: As it turns out, the behaviour I describe below was due to a config discrepancy between the sentry web process and sentry worker instances. So the part that worked was actually using TLS (which works out of the box). I'll leave the relevant part for future reference...


We have a nice case as well :-)
I "borrowed" from https://github.com/creativ/docker-sentry-aws-ses to set Sentry up with SSL support:

  • install django-smtp-ssl==1.0
  • add SENTRY_OPTIONS['mail.backend'] = 'django_smtp_ssl.SSLEmailBackend' to sentry.conf.py
  • use appropriate ENV variables

Seemed like all was well, since a mail sent from https://.../manage/status/mail/ "Send a test mail" yields no errors and the test mail arrives

However: when I go on https://.../account/settings/ and click a "Resend Verification Email" link, I get the error below.

SSLError: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:590)
  File "celery/app/trace.py", line 240, in trace_task
    R = retval = fun(*args, **kwargs)
  File "celery/app/trace.py", line 438, in __protected_call__
    return self.run(*args, **kwargs)
  ...
  File "python2.7/ssl.py", line 830, in do_handshake
    self._sslobj.do_handshake()

@dirkdevriendt : thanks for the workaround! Unfortunately, I can't get this to work. django-smtp-ssl==1.0 is installed and my sentry.conf.py looks like this now:

SENTRY_OPTIONS['mail.backend'] = 'django_smtp_ssl.SSLEmailBackend'
SENTRY_OPTIONS['mail.host'] = 'mail.domain.com'
SENTRY_OPTIONS['mail.port'] = 465
SENTRY_OPTIONS['mail.username'] = '[email protected]'
SENTRY_OPTIONS['mail.password'] = '*****'
SENTRY_OPTIONS['mail.use-tls'] = False
SENTRY_OPTIONS['mail.from'] = SENTRY_OPTIONS['mail.username']
SENTRY_OPTIONS['mail.list-namespace'] = 'domain.com'

I no longer see any errors when sending a test email or account verification email. According to my sentry worker log, messages are sent:

15:00:59 [INFO] sentry.mail: mail.sent (message_id='<[email protected]>')

However, no emails are actually received and it looks like something is failing silently. What am I doing wrong? Does anyone have any tips?

FYI: these are the ENVVARs we have in the configuration; we're on Amazon AWS

SENTRY_EMAIL_BACKEND    django.core.mail.backends.smtp.EmailBackend
SENTRY_EMAIL_HOST       email-smtp.eu-west-1.amazonaws.com
SENTRY_EMAIL_PORT       587
SENTRY_EMAIL_USER       <user_id>
SENTRY_EMAIL_PASSWORD   ***
SENTRY_EMAIL_USE_TLS    True
SENTRY_SERVER_EMAIL     <user_email>

To be clear, I'm not sure non-TLS ever worked for us...

Thanks for the tip! I switched on TLS, but not luck. Something is still failing silently. Which version of Sentry are you running?

In the meantime, back to refreshing the Sentry page on my phone to avoid missing new issues. :frowning_face:

@tkaemming , @mattrobenolt : it would be great to have some kind of officially documented workaround for this, while we wait for the jump to a newer Django version. In any case, thanks for your hard work!

Actually, I found my workaround: the excellent Slack plugin!

so the problem is still there??I want to use sentry.io but , sentry io is kind of slow in my place .and sometimes it's blocked .so we need to deploy on my local server..

@tyan4g we're still on Django 1.6, so it looks like this is sitll a problem

+1

+1

Hi, @tkaemming
I have the same problem, too.
And I tried to solve this by only updating django from 1.6 to 1.11, in my self built docker image.
But after i finished updating django and run the following commands.

$ docker run --rm sentry config generate-secret-key
$ docker run -it --rm -e SENTRY_SECRET_KEY='t7*-1&t*e_o-wyw+y4g6v!95qb9b_77tdc5&ppfvr!+xz^xgu%' --link sentry-postgres:postgres --link sentry-redis:redis sentry upgrade

The error occurs like this:

Traceback (most recent call last):
  File "/usr/local/bin/sentry", line 11, in <module>
    sys.exit(main())
...
  File "/usr/local/lib/python2.7/site-packages/sentry/runner/importer.py", line 44, in load_module
    mod = self._load_module(fullname)
  File "/usr/local/lib/python2.7/site-packages/sentry/runner/importer.py", line 62, in _load_module
    from django.utils.importlib import import_module
sentry.runner.importer.ConfigurationError: ImportError: No module named importlib
...

How should I solve this problem or I can just wait for sentry docker image updating ?
Wish your reply. Thx!

And I tried to solve this by only updating django from 1.6 to 1.11, in my self built docker image.

This is definitely not going to work, as you found out. This is not a trivial change, and in Django land, this is 5 major releases. There are many reasons why we’re locked into 1.6.

How should I solve this problem or I can just wait for sentry docker image updating ?

If django-smtp-ssl doesn’t work or solve the problem, there’s unfortunately nothing we’re going to be able to do until we upgrade Django ourselves, which will be a long time away, if ever.

This issue happens to me, and I find the name of this setting are surprisingly confusing.

There are two kinds of encryption a SMTP connection can use:

  • Use a STARTTLS command over a plain connection to negotiate. This scheme can reuse the port for unencrypted traffic
  • Use a dedicated port like HTTPS, and do TLS handshake on connecting. All SMTP commands are encrypted. This is usually referred to as SMTPS.

Sentry's mail.use-tls = True actually means the former, but the doc doesn't say that. I configured a SMTPS port for it, so Sentry tried to talk plain commands while the mail server expected a TLS handshake, and it hanged there. Setting the right port solves the issue.

PS: SSL is an old name for TLS. TLS has newer versions while all three SSL versions has died. The usage among mail documentation seems to be different.

incase anyone else is having the same problem:

smtp.exmail.qq.com:465 only supports SSL, so you will get an error:

SMTPServerDisconnected 
sentry.tasks.email.send_email
errorConnection unexpectedly closed: timed out

@lambdaq With smtp.exmail.qq.com,you should set port as 25, a working config like this:

SENTRY_EMAIL_HOST=smtp.exmail.qq.com
SENTRY_EMAIL_PASSWORD=password
[email protected]
SENTRY_EMAIL_PORT=25
SENTRY_EMAIL_USE_TLS=True
[email protected]

I also get the same error like:
SMTPServerDisconnected
sentry.tasks.email.send_email
errorConnection unexpectedly closed: timed out

use aliyun smtp service, the confige:
SENTRY_EMAIL_HOST: "smtp.mxhichina.com"
SENTRY_EMAIL_USER: "[email protected]"
SENTRY_EMAIL_PASSWORD: "**"
SENTRY_EMAIL_USE_TLS: "true"
SENTRY_EMAIL_PORT: 465

@Qinzm Maybe you can try set port to 25.

@dirkdevriendt's solution works for me. Just added package to requirements, changed mailer backend in config, started everything with --build and messages were sent :)

But this is not something I expected, it should work out of the box ;-)

So it's still not resolved? I think TLS support is really important

I run sentry by docker-compose way,add python plugins “django-smtp-ssl~=1.0” to requirements.txt;
It's userful.

@duxinxiao
Use TLS and port 587 solve the problem

$> docker run -d --name cb-sentry \
  -e SENTRY_SECRET_KEY='s7*-1&t*e_o-wyw+y4g6v!95qb9b_77tdc5&ppfvr!+xz^xgu%' \
  -e SENTRY_EMAIL_BACKEND='django.core.mail.backends.smtp.EmailBackend'\
  -e SENTRY_EMAIL_HOST='smtp.exmail.com' \
  -e SENTRY_EMAIL_PORT=587 \
  -e SENTRY_EMAIL_USER='[email protected]' \
  -e SENTRY_EMAIL_PASSWORD='xxxx' \
  -e SENTRY_EMAIL_USE_TLS=True \
  -e SENTRY_SERVER_EMAIL='[email protected]' \
  -e SENTRY_TIME_ZONE='Asia/Shanghai' \
  --link sentry-redis:redis \
  --link sentry-postgres:postgres \
  sentry

@ElliotCui Thanks! I will have a try

@ElliotCui how TLS can solve SSL issue? These are 2 different protocols. Our mail server does not support TLS and we had to create custom Sentry image supporting SSL (based on this comment) and we're using it for few months. Your advice isn't related to this issue, which explicitly states that there isn't support for SSL (and it's true).

mail.host: 'smtp.exmail.qq.com'
mail.port: 587
I change the port from 465 to 587, done......... fxxk

I don't know why by for Yandex i use 465 port and SSL in postclient and the only config that worked for me on Sentry 9 is :

mail.backend: 'smtp'  # Use dummy if you want to disable email entirely
mail.host: 'smtp.yandex.ru'
mail.port: 25
mail.username: '[email protected]'
mail.password: 'mypassword'
mail.use-tls: true
mail.from: '[email protected]'

If you look into it more deeply what django with the SMTP library does you you will come to the following.

Not working example
The example below does not work, because the following read on the socket gives no answer and runs in a timeout. My guess is that the socket channel is not encrypted yet and so it does not work correctly. Run python shell for testing.

import smtplib
import socket
socket.setdefaulttimeout(10)
smtpObj = smtplib.SMTP('smtp.yandex.ru', 465)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "smtplib.py", line 256, in __init__
    (code, msg) = self.connect(host, port)
  File "smtplib.py", line 318, in connect
    (code, msg) = self.getreply()
  File "smtplib.py", line 366, in getreply
    + str(e))
smtplib.SMTPServerDisconnected: Connection unexpectedly closed: timed out

Working example

If you connect over port 25 it is possible to do a login and send the mail. The example is not complete but the connection can be established.

import smtplib
import socket
socket.setdefaulttimeout(10)
smtpObj = smtplib.SMTP('smtp.yandex.ru', 25)
smtpObj.starttls()

config.yaml

###############
# Mail Server #
###############

mail.backend: 'smtp'  # Use dummy if you want to disable email entirely
mail.host: 'smtp.yandex.ru'
mail.port: 587
mail.username: '[email protected]'
mail.password: 'password'
mail.use-tls: true
# The email address to send on behalf of
mail.from: '[email protected]'

It works for me!

@AndreyMashukov TLS != SSL 🙄 It was pointed out before.

To me it seems that Sentry only supports STARTTLS, whereas TLS is actually not supported and SSL (the predecessor of TLS) should not be necessary.

Closing this as we are now on Django 1.11 which should support both SSL and TLS (and you really shouldn't be using SSL 🙂 )

Was this page helpful?
0 / 5 - 0 ratings