2017-02-22 06:12:12 +01:00
|
|
|
# Outgoing email
|
|
|
|
|
2018-04-06 02:04:52 +02:00
|
|
|
Zulip needs to be able to send email so it can confirm new users'
|
|
|
|
email addresses and send notifications.
|
|
|
|
|
|
|
|
## How to configure
|
|
|
|
|
|
|
|
1. Identify an outgoing email (SMTP) account where you can have Zulip
|
2021-08-20 21:53:28 +02:00
|
|
|
send mail. If you don't already have one you want to use, see
|
2018-04-06 02:04:52 +02:00
|
|
|
[Email services](#email-services) below.
|
|
|
|
|
2019-07-16 06:09:34 +02:00
|
|
|
1. Fill out the section of `/etc/zulip/settings.py` headed "Outgoing
|
2021-08-20 21:53:28 +02:00
|
|
|
email (SMTP) settings". This includes the hostname and typically
|
docs: Add missing space to compound verbs “log in”, “set up”, etc.
Noun: backup, checkout, cleanup, login, logout, setup, shutdown, signup,
timeout.
Verb: back up, check out, clean up, log in, log out, set up, shut
down, sign up, time out.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-04-25 23:05:38 +02:00
|
|
|
the port to reach your SMTP provider, and the username to log in to
|
2023-02-27 18:19:32 +01:00
|
|
|
it. If your SMTP server does not require authentication, leave
|
|
|
|
`EMAIL_HOST_USER` empty. You'll also want to fill out the noreply
|
|
|
|
email section.
|
2018-04-06 02:04:52 +02:00
|
|
|
|
2019-07-16 06:09:34 +02:00
|
|
|
1. Put the password for the SMTP user account in
|
2018-04-06 02:04:52 +02:00
|
|
|
`/etc/zulip/zulip-secrets.conf` by setting `email_password`. For
|
|
|
|
example: `email_password = abcd1234`.
|
|
|
|
|
2018-04-06 02:39:26 +02:00
|
|
|
Like any other change to the Zulip configuration, be sure to
|
2019-09-30 19:37:56 +02:00
|
|
|
[restart the server](settings.md) to make your changes take
|
2018-04-06 02:39:26 +02:00
|
|
|
effect.
|
|
|
|
|
2019-07-16 06:09:34 +02:00
|
|
|
1. Configure your SMTP server to allows your Zulip server to send
|
|
|
|
emails originating from the email addresses listed in
|
|
|
|
`/etc/zulip/settings.py` as `ZULIP_ADMINISTRATOR`,
|
|
|
|
`NOREPLY_EMAIL_ADDRESS` and if `ADD_TOKENS_TO_NOREPLY_ADDRESS=True`
|
|
|
|
(the default), `TOKENIZED_NOREPLY_EMAIL_ADDRESS`.
|
|
|
|
|
|
|
|
If you don't know how to do this, we recommend using a [free
|
|
|
|
transactional email service](#free-outgoing-email-services); they
|
|
|
|
will guide you through everything you need to do, covering details
|
|
|
|
like configuring DKIM/SPF authentication so your Zulip emails won't
|
|
|
|
be spam filtered.
|
|
|
|
|
|
|
|
1. Use Zulip's email configuration test tool, documented in the
|
|
|
|
[Troubleshooting section](#troubleshooting), to verify that your
|
|
|
|
configuration is working.
|
|
|
|
|
|
|
|
1. Once your configuration is working, restart the Zulip server with
|
2019-09-09 08:34:23 +02:00
|
|
|
`su zulip -c '/home/zulip/deployments/current/scripts/restart-server'`.
|
2018-04-06 02:04:52 +02:00
|
|
|
|
|
|
|
## Email services
|
2017-02-22 06:12:12 +01:00
|
|
|
|
2017-08-16 01:42:44 +02:00
|
|
|
### Free outgoing email services
|
2017-02-22 06:12:12 +01:00
|
|
|
|
2017-08-16 01:42:44 +02:00
|
|
|
For sending outgoing email from your Zulip server, we highly recommend
|
|
|
|
using a "transactional email" service like
|
2018-04-06 02:39:26 +02:00
|
|
|
[Mailgun](https://documentation.mailgun.com/en/latest/quickstart-sending.html#send-via-smtp),
|
2018-05-17 16:28:08 +02:00
|
|
|
[SendGrid](https://sendgrid.com/docs/API_Reference/SMTP_API/integrating_with_the_smtp_api.html),
|
2018-04-06 02:39:26 +02:00
|
|
|
or, for AWS users,
|
2020-03-27 01:32:21 +01:00
|
|
|
[Amazon SES](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-email-smtp.html).
|
2017-08-16 01:42:44 +02:00
|
|
|
These services are designed to send email from servers, and are by far
|
2018-05-17 16:28:08 +02:00
|
|
|
the easiest way to get outgoing email working reliably (Mailgun has
|
|
|
|
the best documentation).
|
2017-08-16 01:42:44 +02:00
|
|
|
|
|
|
|
If you don't have an existing outgoing SMTP provider, don't worry!
|
2018-04-06 02:39:26 +02:00
|
|
|
Each of the options we recommend above (as well as dozens of other
|
2021-08-20 21:53:28 +02:00
|
|
|
services) have free options. Once you've signed up, you'll want to
|
2018-04-06 02:39:26 +02:00
|
|
|
find the service's provided "SMTP credentials", and configure Zulip as
|
|
|
|
follows:
|
2017-08-16 01:42:44 +02:00
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- The hostname like `EMAIL_HOST = 'smtp.mailgun.org'` in `/etc/zulip/settings.py`
|
|
|
|
- The username like `EMAIL_HOST_USER = 'username@example.com'` in
|
2017-08-16 01:42:44 +02:00
|
|
|
`/etc/zulip/settings.py`.
|
2021-08-20 21:45:39 +02:00
|
|
|
- The TLS setting as `EMAIL_USE_TLS = True` in
|
2018-04-06 02:39:26 +02:00
|
|
|
`/etc/zulip/settings.py`, for most providers
|
2021-08-20 21:45:39 +02:00
|
|
|
- The port as `EMAIL_PORT = 587` in `/etc/zulip/settings.py`, for most
|
2018-04-06 02:39:26 +02:00
|
|
|
providers
|
2021-08-20 21:45:39 +02:00
|
|
|
- The password like `email_password = abcd1234` in `/etc/zulip/zulip-secrets.conf`.
|
2017-08-16 01:42:44 +02:00
|
|
|
|
2023-12-16 19:18:16 +01:00
|
|
|
If your SMTP provider uses implicit SSL/TLS on port 465 (and not `STARTTLS` on
|
|
|
|
port 587), you need to set `EMAIL_PORT = 465`, as well as replacing
|
|
|
|
[`EMAIL_USE_TLS = True`](https://docs.djangoproject.com/en/5.0/ref/settings/#std-setting-EMAIL_USE_TLS)
|
|
|
|
with [`EMAIL_USE_SSL = True`](https://docs.djangoproject.com/en/5.0/ref/settings/#std-setting-EMAIL_USE_SSL).
|
|
|
|
|
2018-11-30 21:04:22 +01:00
|
|
|
### Using system email
|
|
|
|
|
|
|
|
If you'd like to send outgoing email using the local operating
|
2024-07-04 12:33:43 +02:00
|
|
|
system's email delivery configuration (e.g., you have `postfix`
|
2018-11-30 21:04:22 +01:00
|
|
|
configuration on the system that forwards email sent locally into your
|
|
|
|
corporate email system), you will likely need to use something like
|
|
|
|
these setting values:
|
|
|
|
|
2021-08-20 07:09:04 +02:00
|
|
|
```python
|
2018-11-30 21:04:22 +01:00
|
|
|
EMAIL_HOST = 'localhost'
|
|
|
|
EMAIL_PORT = 25
|
|
|
|
EMAIL_USE_TLS = False
|
|
|
|
EMAIL_HOST_USER = ""
|
|
|
|
```
|
|
|
|
|
|
|
|
We should emphasize that because modern spam filtering is very
|
|
|
|
aggressive, you should make sure your downstream email system is
|
|
|
|
configured to properly sign outgoing email sent by your Zulip server
|
2021-08-20 21:53:28 +02:00
|
|
|
(or check your spam folder) when using this configuration. See
|
2018-11-30 21:04:22 +01:00
|
|
|
[documentation on using Django with a local postfix server][postfix-email]
|
|
|
|
for additional advice.
|
|
|
|
|
|
|
|
[postfix-email]: https://stackoverflow.com/questions/26333009/how-do-you-configure-django-to-send-mail-through-postfix
|
|
|
|
|
2017-08-16 01:42:44 +02:00
|
|
|
### Using Gmail for outgoing email
|
|
|
|
|
|
|
|
We don't recommend using an inbox product like Gmail for outgoing
|
2021-08-20 21:53:28 +02:00
|
|
|
email, because Gmail's anti-spam measures make this annoying. But if
|
2017-08-16 01:42:44 +02:00
|
|
|
you want to use a Gmail account to send outgoing email anyway, here's
|
|
|
|
how to make it work:
|
2021-08-20 22:54:08 +02:00
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- Create a totally new Gmail account for your Zulip server; you don't
|
2017-10-12 20:38:01 +02:00
|
|
|
want Zulip's automated emails to come from your personal email address.
|
2021-08-20 21:45:39 +02:00
|
|
|
- If you're using 2-factor authentication on the Gmail account, you'll
|
2017-10-12 20:38:01 +02:00
|
|
|
need to use an
|
|
|
|
[app-specific password](https://support.google.com/accounts/answer/185833).
|
2021-08-20 21:45:39 +02:00
|
|
|
- If you're not using 2-factor authentication, read this Google
|
2017-10-12 20:38:01 +02:00
|
|
|
support answer and configure that account as
|
|
|
|
["less secure"](https://support.google.com/accounts/answer/6010255);
|
|
|
|
Gmail doesn't allow servers to send outgoing email by default.
|
2021-08-20 21:45:39 +02:00
|
|
|
- Note also that the rate limits for Gmail are also quite low
|
2024-07-04 12:33:43 +02:00
|
|
|
(e.g., 100 / day), so it's easy to get rate-limited if your server
|
2021-08-20 21:53:28 +02:00
|
|
|
has significant traffic. For more active servers, we recommend
|
2018-04-06 02:39:26 +02:00
|
|
|
moving to a free account on a transactional email service.
|
2017-02-22 06:12:12 +01:00
|
|
|
|
|
|
|
### Logging outgoing email to a file for prototyping
|
|
|
|
|
2018-04-06 02:39:26 +02:00
|
|
|
For prototyping, you might want to proceed without setting up an email
|
2021-08-20 21:53:28 +02:00
|
|
|
provider. If you want to see the emails Zulip would have sent, you
|
2018-04-06 02:39:26 +02:00
|
|
|
can log them to a file instead.
|
|
|
|
|
|
|
|
To do so, add these lines to `/etc/zulip/settings.py`:
|
2017-02-22 06:12:12 +01:00
|
|
|
|
2021-08-20 07:09:04 +02:00
|
|
|
```python
|
2017-02-22 06:12:12 +01:00
|
|
|
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
|
2017-05-25 02:35:02 +02:00
|
|
|
EMAIL_FILE_PATH = '/var/log/zulip/emails'
|
2017-02-22 06:12:12 +01:00
|
|
|
```
|
|
|
|
|
2018-04-06 02:39:26 +02:00
|
|
|
Then outgoing emails that Zulip would have sent will just be written
|
|
|
|
to files in `/var/log/zulip/emails/`.
|
2017-02-22 06:12:12 +01:00
|
|
|
|
2018-04-06 02:39:26 +02:00
|
|
|
Remember to delete this configuration (and restart the server) if you
|
|
|
|
later set up a real SMTP provider!
|
2017-02-22 06:12:12 +01:00
|
|
|
|
2018-04-06 02:04:52 +02:00
|
|
|
## Troubleshooting
|
2017-02-22 06:12:12 +01:00
|
|
|
|
|
|
|
You can quickly test your outgoing email configuration using:
|
|
|
|
|
2021-08-20 07:09:04 +02:00
|
|
|
```bash
|
2018-07-30 22:38:11 +02:00
|
|
|
su zulip -c '/home/zulip/deployments/current/manage.py send_test_email user@example.com'
|
2017-02-22 06:12:12 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
If it doesn't throw an error, it probably worked; you can confirm by
|
2021-08-20 21:53:28 +02:00
|
|
|
checking your email. You should get two emails: One sent by the
|
2018-05-27 20:13:23 +02:00
|
|
|
default From address for your Zulip server, and one sent by the
|
|
|
|
"noreply" From address.
|
2017-02-22 06:12:12 +01:00
|
|
|
|
2018-04-06 02:39:26 +02:00
|
|
|
If it doesn't work, check these common failure causes:
|
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- Your hosting provider may block outgoing SMTP traffic in its default
|
2021-08-20 21:53:28 +02:00
|
|
|
firewall rules. Check whether the port `EMAIL_PORT` is blocked in
|
2018-04-06 02:39:26 +02:00
|
|
|
your hosting provider's firewall.
|
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- Your SMTP server's permissions might not allow the email account
|
2018-06-20 20:26:21 +02:00
|
|
|
you're using to send email from the `noreply` email addresses used
|
|
|
|
by Zulip when sending confirmation emails.
|
|
|
|
|
|
|
|
For security reasons, Zulip sends confirmation emails (used for
|
|
|
|
account creation, etc.) with randomly generated from addresses
|
|
|
|
starting with `noreply-`.
|
|
|
|
|
|
|
|
If necessary, you can set `ADD_TOKENS_TO_NOREPLY_ADDRESS` to `False`
|
|
|
|
in `/etc/zulip/settings.py` (which will cause these confirmation
|
2021-08-20 21:53:28 +02:00
|
|
|
emails to be sent from a consistent `noreply@` address). Disabling
|
2018-06-20 20:26:21 +02:00
|
|
|
`ADD_TOKENS_TO_NOREPLY_ADDRESS` is generally safe if you are not
|
|
|
|
using Zulip's feature that allows anyone to create an account in
|
|
|
|
your Zulip organization if they have access to an email address in a
|
2021-08-20 21:53:28 +02:00
|
|
|
certain domain. See [this article][helpdesk-attack] for details on
|
2018-06-20 20:26:21 +02:00
|
|
|
the security issue with helpdesk software that
|
|
|
|
`ADD_TOKENS_TO_NOREPLY_ADDRESS` helps protect against.
|
2018-05-27 20:13:23 +02:00
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- Make sure you set the password in `/etc/zulip/zulip-secrets.conf`.
|
2017-02-22 06:12:12 +01:00
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- Check the username and password for typos.
|
2017-02-22 06:12:12 +01:00
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- Be sure to restart your Zulip server after editing either
|
2018-04-06 02:39:26 +02:00
|
|
|
`settings.py` or `zulip-secrets.conf`, using
|
|
|
|
`/home/zulip/deployments/current/scripts/restart-server` .
|
|
|
|
Note that the `manage.py` command above will read the latest
|
|
|
|
configuration from the config files, even if the server is still
|
|
|
|
running with an old configuration.
|
2017-02-22 06:12:12 +01:00
|
|
|
|
2018-04-06 02:04:52 +02:00
|
|
|
### Advanced troubleshooting
|
2017-02-22 06:12:12 +01:00
|
|
|
|
2017-09-26 00:35:42 +02:00
|
|
|
Here are a few final notes on what to look at when debugging why you
|
|
|
|
aren't receiving emails from Zulip:
|
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- Most transactional email services have an "outgoing email" log where
|
2018-04-06 02:39:26 +02:00
|
|
|
you can inspect the emails that reached the service, whether an
|
|
|
|
email was flagged as spam, etc.
|
|
|
|
|
2024-08-20 20:25:13 +02:00
|
|
|
- Zulip logs an entry in `/var/log/zulip/send_email.log` whenever it
|
|
|
|
attempts to send an email. The log entry includes whether the
|
|
|
|
request succeeded or failed.
|
2018-04-06 02:39:26 +02:00
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- If attempting to send an email throws an exception, a traceback
|
2017-09-26 00:35:42 +02:00
|
|
|
should be in `/var/log/zulip/errors.log`, along with any other
|
|
|
|
exceptions Zulip encounters.
|
2018-04-06 02:39:26 +02:00
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- Zulip's email sending configuration is based on the standard Django
|
2024-05-24 16:57:31 +02:00
|
|
|
[SMTP backend](https://docs.djangoproject.com/en/5.0/topics/email/#smtp-backend)
|
2021-08-20 21:53:28 +02:00
|
|
|
configuration. So if you're having trouble getting your email
|
2017-10-12 20:29:10 +02:00
|
|
|
provider working, you may want to search for documentation related
|
2018-04-06 02:39:26 +02:00
|
|
|
to using your email provider with Django.
|
|
|
|
|
|
|
|
The one thing we've changed from the Django defaults is that we read
|
|
|
|
the email password from the `email_password` entry in the Zulip
|
|
|
|
secrets file, as part of our policy of not having any secret
|
2021-08-20 21:53:28 +02:00
|
|
|
information in the `/etc/zulip/settings.py` file. In other words,
|
2018-04-06 02:39:26 +02:00
|
|
|
if Django documentation references setting `EMAIL_HOST_PASSWORD`,
|
|
|
|
you should instead set `email_password` in
|
|
|
|
`/etc/zulip/zulip-secrets.conf`.
|
2018-06-20 20:26:21 +02:00
|
|
|
|
|
|
|
[helpdesk-attack]: https://medium.com/intigriti/how-i-hacked-hundreds-of-companies-through-their-helpdesk-b7680ddc2d4c
|