docs: Complete rewrite of Relay Host pages (#3861)

* docs: Complete rewrite on relay host docs

- Both relay docs pages have had heavy refactor / rewrite.
- ENV docs page relay host section revised.

* docs: Revise relay host page with technical details section

* docs: Add LDAP compatibility caveat for `RELAY_HOST`
This commit is contained in:
Brennan Kinney 2024-01-31 23:11:19 +13:00 committed by GitHub
parent d65b2f35a7
commit d426f724cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 203 additions and 87 deletions

View File

@ -2,29 +2,46 @@
title: 'Mail Forwarding | AWS SES'
---
[Amazon SES (Simple Email Service)](https://aws.amazon.com/ses/) is intended to provide a simple way for cloud based applications to send email and receive email. For the purposes of this project only sending email via SES is supported. Older versions of docker-mailserver used `AWS_SES_HOST` and `AWS_SES_USERPASS` to configure sending, this has changed and the setup is managed through [Configure Relay Hosts][docs-relay].
[Amazon SES (Simple Email Service)][aws-ses] provides a simple way for cloud based applications to send and receive email.
You will need to create some [Amazon SES SMTP credentials](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/smtp-credentials.html). The SMTP credentials you create will be used to populate the `RELAY_USER` and `RELAY_PASSWORD` environment variables.
!!! example "Configuration via ENV"
The `RELAY_HOST` should match your [AWS SES region](https://docs.aws.amazon.com/general/latest/gr/ses.html), the `RELAY_PORT` will be 587.
[Configure a relay host in DMS][docs::relay] to forward all your mail through AWS SES:
If all of your email is being forwarded through AWS SES, `DEFAULT_RELAY_HOST` should be set accordingly.
- `RELAY_HOST` should match your [AWS SES region][aws-ses::region].
- `RELAY_PORT` should be set to [one of the supported AWS SES SMTP ports][aws-ses::smtp-ports] (_eg: 587 for STARTTLS_).
- `RELAY_USER` and `RELAY_PASSWORD` should be set to your [Amazon SES SMTP credentials][aws-ses::credentials].
Example:
```
DEFAULT_RELAY_HOST=[email-smtp.us-west-2.amazonaws.com]:587
```
```env
RELAY_HOST=email-smtp.us-west-2.amazonaws.com
RELAY_PORT=587
# Alternative to RELAY_HOST + RELAY_PORT which is compatible with LDAP:
DEFAULT_RELAY_HOST=[email-smtp.us-west-2.amazonaws.com]:587
!!! note
If you set up [AWS Easy DKIM](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-email-authentication-dkim-easy.html) you can safely skip setting up DKIM as the AWS SES will take care of signing your outgoing email.
RELAY_USER=aws-user
RELAY_PASSWORD=secret
```
To verify proper operation, send an email to some external account of yours and inspect the mail headers. You will also see the connection to SES in the mail logs. For example:
!!! tip
```log
May 23 07:09:36 mail postfix/smtp[692]: Trusted TLS connection established to email-smtp.us-east-1.amazonaws.com[107.20.142.169]:25:
TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
May 23 07:09:36 mail postfix/smtp[692]: 8C82A7E7: to=<someone@example.com>, relay=email-smtp.us-east-1.amazonaws.com[107.20.142.169]:25,
delay=0.35, delays=0/0.02/0.13/0.2, dsn=2.0.0, status=sent (250 Ok 01000154dc729264-93fdd7ea-f039-43d6-91ed-653e8547867c-000000)
```
If you have set up [AWS Easy DKIM][aws-ses::easy-dkim], you can safely skip setting up DKIM as AWS SES will take care of signing your outbound mail.
[docs-relay]: ./relay-hosts.md
!!! note "Verify the relay host is configured correctly"
To verify proper operation, send an email to some external account of yours and inspect the mail headers.
You will also see the connection to SES in the mail logs:
```log
postfix/smtp[692]: Trusted TLS connection established to email-smtp.us-west-1.amazonaws.com[107.20.142.169]:25:
TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
postfix/smtp[692]: 8C82A7E7: to=<someone@example.com>, relay=email-smtp.us-west-1.amazonaws.com[107.20.142.169]:25,
delay=0.35, delays=0/0.02/0.13/0.2, dsn=2.0.0, status=sent (250 Ok 01000154dc729264-93fdd7ea-f039-43d6-91ed-653e8547867c-000000)
```
[docs::relay]: ./relay-hosts.md
[aws-ses]: https://aws.amazon.com/ses/
[aws-ses::credentials]: https://docs.aws.amazon.com/ses/latest/dg/smtp-credentials.html
[aws-ses::smtp-ports]: https://docs.aws.amazon.com/ses/latest/dg/smtp-connect.html
[aws-ses::region]: https://docs.aws.amazon.com/general/latest/gr/ses.html
[aws-ses::easy-dkim]: https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-email-authentication-dkim-easy.html

View File

@ -2,82 +2,155 @@
title: 'Mail Forwarding | Relay Hosts'
---
## Introduction
## What is a Relay Host?
Rather than having Postfix deliver mail directly, you can configure Postfix to send mail via another mail relay (smarthost). Examples include [Mailgun](https://www.mailgun.com/), [Sendgrid](https://sendgrid.com/) and [AWS SES](https://aws.amazon.com/ses/).
An SMTP relay service (_aka relay host / [smarthost][wikipedia::smarthost]_) is an MTA that relays (_forwards_) mail on behalf of third-parties (_it does not manage the mail domains_).
Depending on the domain of the sender, you may want to send via a different relay, or authenticate in a different way.
- Instead of DMS handling SMTP delivery directly itself (_via Postfix_), it can be configured to delegate delivery by sending all outbound mail through a relay service.
- Examples of popular mail relay services: [AWS SES][smarthost::aws-ses], [Mailgun][smarthost::mailgun], [Mailjet][smarthost::mailjet], [SendGrid][smarthost::sendgrid]
## Basic Configuration
!!! info "When can a relay service can be helpful?"
Basic configuration is done via environment variables:
- Your network provider has blocked outbound connections on port 25 (_required for direct delivery_).
- To improve delivery success via better established reputation (trust) of a relay service.
- `RELAY_HOST`: _default host to relay mail through, `empty` (aka '', or no ENV set) will disable this feature_
- `RELAY_PORT`: _port on default relay, defaults to port 25_
- `RELAY_USER`: _username for the default relay_
- `RELAY_PASSWORD`: _password for the default user_
## Configuration
Setting these environment variables will cause mail for all sender domains to be routed via the specified host, authenticating with the user/password combination.
All mail sent outbound from DMS (_where the sender address is a DMS account or a virtual alias_) will be relayed through the configured relay host.
!!! warning
For users of the previous `AWS_SES_*` variables: please update your configuration to use these new variables, no other configuration is required.
!!! info "Configuration via ENV"
## Advanced Configuration
Configure the default relayhost with either of these ENV:
### Sender-dependent Authentication
- Preferable (_LDAP compatible_): `DEFAULT_RELAY_HOST` (eg: `[mail.relay-service.com]:25`)
- `RELAY_HOST` (eg: `mail.relay-service.com`) + `RELAY_PORT` (default: 25)
Sender dependent authentication is done in `docker-data/dms/config/postfix-sasl-password.cf`. You can create this file manually, or use:
Most relay services also require authentication configured:
```sh
setup.sh relay add-auth <domain> <username> [<password>]
```
- `RELAY_USER` + `RELAY_PASSWORD` provides credentials for authenticating with the default relayhost.
An example configuration file looks like this:
!!! warning "Providing secrets via ENV"
```txt
@domain1.com relay_user_1:password_1
@domain2.com relay_user_2:password_2
```
While ENV is convenient, the risk of exposing secrets is higher.
If there is no other configuration, this will cause Postfix to deliver email through the relay specified in `RELAY_HOST` env variable, authenticating as `relay_user_1` when sent from `domain1.com` and authenticating as `relay_user_2` when sending from `domain2.com`.
`setup relay add-auth` is a better alternative, which manages the credentials via a config file.
!!! note
To activate the configuration you must either restart the container, or you can also trigger an update by modifying a mail account.
??? tip "Excluding specific sender domains from relay"
### Sender-dependent Relay Host
You can opt-out with: `setup relay exclude-domain <domain>`
Sender dependent relay hosts are configured in `docker-data/dms/config/postfix-relaymap.cf`. You can create this file manually, or use:
Outbound mail from senders of that domain will be sent normally (_instead of through the configured `RELAY_HOST`_).
```sh
setup.sh relay add-domain <domain> <host> [<port>]
```
!!! warning "When any relay host credentials are configured"
An example configuration file looks like this:
It will still be expected that mail is sent over a secure connection with credentials provided.
```txt
@domain1.com [relay1.org]:587
@domain2.com [relay2.org]:2525
```
Thus this opt-out feature is rarely practical.
Combined with the previous configuration in `docker-data/dms/config/postfix-sasl-password.cf`, this will cause Postfix to deliver mail sent from `domain1.com` via `relay1.org:587`, authenticating as `relay_user_1`, and mail sent from `domain2.com` via `relay2.org:2525` authenticating as `relay_user_2`.
### Advanced Configuration
!!! note
You still have to define `RELAY_HOST` to activate the feature
When mail is sent, there is support to change the relay service or the credentials configured based on the sender address domain used.
### Excluding Sender Domains
We provide this support via two config files:
If you want mail sent from some domains to be delivered directly, you can exclude them from being delivered via the default relay by adding them to `docker-data/dms/config/postfix-relaymap.cf` with no destination. You can also do this via:
- Sender-dependent Relay Host: `docker-data/dms/config/postfix-relaymap.cf`
- Sender-dependent Authentication: `docker-data/dms/config/postfix-sasl-password.cf`
```sh
setup.sh relay exclude-domain <domain>
```
!!! tip "Configure with our `setup relay` commands"
Extending the configuration file from above:
While you can edit those configs directly, DMS provides these helpful config management commands:
```txt
@domain1.com [relay1.org]:587
@domain2.com [relay2.org]:2525
@domain3.com
```
```cli-syntax
# Configure a sender domain to use a specific relay host:
setup relay add-domain <domain> <host> [<port>]
This will cause email sent from `domain3.com` to be delivered directly.
# Configure relay host credentials for a sender domain to use:
setup relay add-auth <domain> <username> [<password>]
# Optionally avoid relaying from senders of this domain:
# NOTE: Only supported when configured with the `RELAY_HOST` ENV!
setup relay exclude-domain <domain>
```
!!! example "Config file: `postfix-sasl-password.cf`"
```cf-extra title="docker-data/dms/config/postfix-sasl-password.cf"
@domain1.com mailgun-user:secret
@domain2.com sendgrid-user:secret
# NOTE: This must have an exact match with the relay host in `postfix-relaymap.cf`,
# `/etc/postfix/relayhost_map`, or the `DEFAULT_RELAY_HOST` ENV.
# NOTE: Not supported via our setup CLI, but valid config for Postfix.
[email-smtp.us-west-2.amazonaws.com]:2587 aws-user:secret
```
When Postfix needs to lookup credentials for mail sent outbound, the above config will:
- Authenticate as `mailgun-user` for mail sent with a sender belonging to `@domain1.com`
- Authenticate as `sendgrid-user` for mail sent with a sender belonging to `@domain2.com`
- Authenticate as `aws-user` for mail sent through a configured AWS SES relay host (any sender domain).
!!! example "Config file: `postfix-relaymap.cf`"
```cf-extra title="docker-data/dms/config/postfix-relaymap.cf"
@domain1.com [smtp.mailgun.org]:587
@domain2.com [smtp.sendgrid.net]:2525
# Opt-out of relaying:
@domain3.com
```
When Postfix sends mail outbound from these sender domains, the above config will:
- Relay mail through `[smtp.mailgun.org]:587` when mail is sent from a sender of `@domain1.com`
- Relay mail through `[smtp.sendgrid.net]:2525` when mail is sent from a sender of `@domain1.com`
- Mail with a sender from `@domain3.com` is not sent through a relay (_**Only applicable** when using `RELAY_HOST`_)
### Technical Details
- Both the supported ENV and config files for this feature have additional details covered in our ENV docs [Relay Host section][docs::env-relay].
- For troubleshooting, a [minimal `compose.yaml` config with several DMS instances][dms-gh::relay-example] demonstrates this feature for local testing.
- [Subscribe to this tracking issue][dms-gh::pr-3607] for future improvements intended for this feature.
!!! abstract "Postfix Settings"
Internally this feature is implemented in DMS by [`relay.sh`][dms-repo::helpers-relay].
The `relay.sh` script manages configuring these Postfix settings:
```cf-extra
# Send all outbound mail through this relay service:
relayhost = [smtp.relay-service.com]:587
# Credentials to use:
smtp_sasl_password_maps = texthash:/etc/postfix/sasl_passwd
# Alternative table type examples which do not require a separate file:
#smtp_sasl_password_maps = static:john.doe@relay-service.com:secret
#smtp_sasl_password_maps = inline:{ [smtp.relay-service.com]:587=john.doe@relay-service.com:secret }
## Authentication support:
# Required to provide credentials to the relay service:
smtp_sasl_auth_enable = yes
# Enforces requiring credentials when sending mail outbound:
smtp_sasl_security_options = noanonymous
# Enforces a secure connection (TLS required) to the relay service:
smtp_tls_security_level = encrypt
## Support for advanced requirements:
# Relay service(s) to use instead of direct delivery for specific sender domains:
sender_dependent_relayhost_maps = texthash:/etc/postfix/relayhost_map
# Support credentials to a relay service(s) that vary by relay host used or sender domain:
smtp_sender_dependent_authentication = yes
```
[smarthost::mailgun]: https://www.mailgun.com/
[smarthost::mailjet]: https://www.mailjet.com
[smarthost::sendgrid]: https://sendgrid.com/
[smarthost::aws-ses]: https://aws.amazon.com/ses/
[wikipedia::smarthost]: https://en.wikipedia.org/wiki/Smart_host
[docs::env-relay]: ../../environment.md#relay-host
[dms-repo::helpers-relay]: https://github.com/docker-mailserver/docker-mailserver/blob/v14.0.0/target/scripts/helpers/relay.sh
[dms-gh::pr-3607]: https://github.com/docker-mailserver/docker-mailserver/issues/3607
[dms-gh::relay-example]: https://github.com/docker-mailserver/docker-mailserver/issues/3842#issuecomment-1913380639

View File

@ -1014,13 +1014,19 @@ you to replace both instead of just the envelope sender.
#### Relay Host
!!! tip "`RELAY_HOST` vs `DEFAULT_RELAY_HOST`"
Supported ENV for the [Relay Host][docs::relay-host] feature.
`DEFAULT_RELAY_HOST` is encouraged, but presently does not support sender domain opt-out (`setup relay exclude-domain`).
!!! note "Prefer `DEFAULT_RELAY_HOST` instead of `RELAY_HOST`"
This is advised unless you need support for sender domain opt-out (via `setup relay exclude-domain`).
The implementation for `RELAY_HOST` is not compatible with LDAP.
!!! tip "Opt-in for relay host support"
If you only want to enable relay for specific sender domains, use can use opt-in via `setup relay add-domain`.
Enable relaying only for specific sender domains instead by using `setup relay add-domain`.
**NOTE:** Presently there is a caveat when relay host credentials are configured (_which is incompatible with opt-in_).
##### DEFAULT_RELAY_HOST
@ -1033,22 +1039,24 @@ Configures a default relay host.
!!! abstract "Technical Details"
Configures the Postfix `main.cf` setting: [`relayhost`][postfix-config::relayhost]
This ENV internally configures the Postfix `main.cf` setting: [`relayhost`][postfix-config::relayhost]
##### RELAY_HOST
Configures a default relay host.
!!! info
- This is a legacy ENV. It is however required for the opt-out feature of `postfix-relaymap.cf` to work.
- When configured, all known mail domains managed by DMS will be configured to relay outbound mail, just like `DEFAULT_RELAY_HOST`.
!!! note
Expects a value like `mail.example.com`. Internally this will be wrapped to `[mail.example.com]`, so it should resolve to the MTA directly.
Do not use with `DEFAULT_RELAY_HOST`. `RELAY_HOST` has precedence as it is configured with `sender_dependent_relayhost_maps`.
!!! warning "Do not use with `DEFAULT_RELAY_HOST`"
`RELAY_HOST` has precedence as it is configured with `sender_dependent_relayhost_maps`.
!!! info
- This is a legacy ENV. It is however required for the opt-out feature of `postfix-relaymap.cf` to work.
- Internal configuration however differs from `DEFAULT_RELAY_HOST`.
!!! abstract "Technical Details"
@ -1057,6 +1065,8 @@ Configures a default relay host.
- Postfix setting with config: [`sender_dependent_relayhost_maps = texthash:/etc/postfix/relayhost_map`][postfix-config::relayhost_maps]
- DMS Config volume support via: `postfix-relaymap.cf` (_generates `/etc/postfix/relayhost_map`_)
All known mail domains managed by DMS will be configured to relay outbound mail to `RELAY_HOST` by adding them implicitly to `/etc/postfix/relayhost_map`, except for domains using the opt-out feature of `postfix-relaymap.cf`.
##### RELAY_PORT
Default => 25
@ -1069,10 +1079,10 @@ Support for configuring a different port than 25 for `RELAY_HOST` to use.
#### Relay Host Credentials
!!! warning "Configuring relay host credentials make outbound authentication mandatory"
!!! warning "Configuring relay host credentials enforces outbound authentication"
Presently when `RELAY_USER` + `RELAY_PASSWORD` or `postfix-sasl-password.cf` are configured, all outbound mail traffic is configured to require a secure connection established and forbids the omission of credentials.
Additional feature work is required to only enforce these requirements on mail sent through a configured relay host.
##### RELAY_USER
@ -1083,10 +1093,10 @@ Provide the credentials to use with `RELAY_HOST` or `DEFAULT_RELAY_HOST`.
!!! tip "Alternative credentials config"
You may prefer to use `setup relay add-auth` to avoid exposure of secrets in ENV.
You may prefer to use `setup relay add-auth` to avoid risking ENV exposing secrets.
- With the CLI command you must provide each sender domain relay credentials.
- Alternatively manually edit `postfix-sasl-password.cf` with the correct relayhost entry (_`DEFAULT_RELAY_HOST` value or as defined in `/etc/postfix/relayhost_map`_) to provide credentials per relayhost configured.
- With the CLI command, you must provide relay credentials for each of your sender domains.
- Alternatively manually edit `postfix-sasl-password.cf` with the correct relayhost entry (_`DEFAULT_RELAY_HOST` value, or as defined in `/etc/postfix/relayhost_map`_) to provide credentials per relayhost configured.
!!! abstract "Technical Details"
@ -1095,7 +1105,16 @@ Provide the credentials to use with `RELAY_HOST` or `DEFAULT_RELAY_HOST`.
- Postfix setting with config: [`smtp_sasl_password_maps = texthash:/etc/postfix/sasl_passwd`][postfix-config::sasl_passwd]
- DMS Config volume support via: `postfix-sasl-password.cf` (_generates `/etc/postfix/sasl_passwd`_)
This file has relay hosts that must match the `host:port` of `/etc/postfix/relayhost_map` or `main.cf:relayhost`. DMS support handles this for you.
---
When `postfix-sasl-password.cf` is present, DMS will copy it internally to `/etc/postfix/sasl_passwd`.
- DMS provides support for mapping credentials by sender domain:
- Explicitly via `setup relay add-auth` (_creates / updates `postfix-sasl-password.cf`_).
- Implicitly via the relay ENV support (_configures all known DMS managed domains to use the relay ENV_).
- Credentials can be explicitly configured for specific relay hosts instead of sender domains:
- Add the exact relayhost value (`host:port` / `[host]:port`) from the generated `/etc/postfix/relayhost_map`, or `main.cf:relayhost` (`DEFAULT_RELAY_HOST`).
- `setup relay ...` is missing support, you must instead add these manually to `postfix-sasl-password.cf`.
[docs-rspamd]: ./security/rspamd.md
[docs-tls]: ./security/ssl.md
@ -1103,6 +1122,7 @@ Provide the credentials to use with `RELAY_HOST` or `DEFAULT_RELAY_HOST`.
[docs-tls-manual]: ./security/ssl.md#bring-your-own-certificates
[docs-tls-selfsigned]: ./security/ssl.md#self-signed-certificates
[docs-accounts-quota]: ./user-management.md#quotas
[docs::relay-host]: ./advanced/mail-forwarding/relay-hosts.md
[docs::dms-volumes-state]: ./advanced/optional-config.md#volumes-state
[postfix-config::relayhost]: https://www.postfix.org/postconf.5.html#relayhost
[postfix-config::relayhost_maps]: https://www.postfix.org/postconf.5.html#sender_dependent_relayhost_maps

View File

@ -89,6 +89,7 @@ markdown_extensions:
emoji_index: !!python/name:material.extensions.emoji.twemoji
emoji_generator: !!python/name:material.extensions.emoji.to_svg
- pymdownx.highlight:
# Configures an alias (name) to a supported syntax (lang):
extend_pygments_lang:
- name: yml
lang: yaml
@ -98,8 +99,13 @@ markdown_extensions:
lang: cfg
- name: env
lang: properties
# Not helpful with Python Pygments lexer highlighting, but we might change to a JS highlighter in future
# Ideally, this type of codefence might also have word-wrap enabled (CSS: {white-space: pre-wrap})
# A variant that sometimes has nicer syntax highlighting:
- name: cf-extra
lang: linuxconfig
- name: cli-syntax
lang: linuxconfig
# These formats aren't supported by Python Pygments lexer,
# but we use them when the context is appropriate.
- name: log
lang: shell-session
- name: fetchmailrc