Merge branch 'master' into docs/misc-improvements

This commit is contained in:
Georg Lauterbach 2024-02-01 18:35:07 +01:00 committed by GitHub
commit 0d65cca3d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 541 additions and 225 deletions

View File

@ -36,6 +36,21 @@ The most noteworthy change of this release is the update of the container's base
- DMS `main.cf` has renamed `postscreen_dnsbl_whitelist_threshold` to `postscreen_dnsbl_allowlist_threshold` as part of this change.
- `smtpd_relay_restrictions` (relay policy) is now evaluated after `smtpd_recipient_restrictions` (spam policy). Previously it was evaluated before `smtpd_recipient_restrictions`. Mail to be relayed via DMS must now pass through the spam policy first.
- The TLS fingerprint policy has changed the default from MD5 to SHA256 (_DMS does not modify this Postfix parameter, but may affect any user customizations that do_).
- **rsyslog:**
- Debian 12 adjusted the `rsyslog` configuration for the default file template from `RSYSLOG_TraditionalFileFormat` to `RSYSLOG_FileFormat` (_upstream default since 2012_). This change may affect you if you have any monitoring / analysis of log output (_eg: `mail.log` / `docker logs`_).
- The two formats are roughly equivalent to [RFC 3164](https://www.rfc-editor.org/rfc/rfc3164)) and [RFC 5424](https://datatracker.ietf.org/doc/html/rfc5424#section-1) respectively.
- A notable difference is the change to [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339.html#appendix-A) timestamps (_a strict subset of ISO 8601_). The [previous non-standardized timestamp format was defined in RFC 3164](https://www.rfc-editor.org/rfc/rfc3164.html#section-4.1.2) as `Mmm dd hh:mm:ss`.
- To revert this change you can add `sedfile -i '1i module(load="builtin:omfile" template="RSYSLOG_TraditionalFileFormat")' /etc/rsyslog.conf` via [our `user-patches.sh` feature](https://docker-mailserver.github.io/docker-mailserver/v14.0/config/advanced/override-defaults/user-patches/).
- Rsyslog now creates fewer log files:
- The files `/var/log/mail/mail.{info,warn,err}` are no longer created. These files represented `/var/log/mail.log` filtered into separate priority levels. As `/var/log/mail.log` contains all mail related messages, these files (_and their rotated counterparts_) can be deleted safely.
- `/var/log/messages`, `/var/log/debug` and several other log files not relevant to DMS were configured by default by Debian previously. These are not part of the `/var/log/mail/` volume mount, so should not impact anyone.
- **Features:**
- The relay host feature was refactored ([#3845](https://github.com/docker-mailserver/docker-mailserver/pull/3845))
- The only breaking change this should introduce is with the Change Detection service (`check-for-changes.sh`).
- When credentials are configured for relays, change events that trigger the relayhost logic now reapply the relevant Postfix settings:
- `smtp_sasl_auth_enable = yes` (_SASL auth to outbound MTA connections is enabled_)
- `smtp_sasl_security_options = noanonymous` (_credentials are mandatory for outbound mail delivery_)
- `smtp_tls_security_level = encrypt` (_the outbound MTA connection must always be secure due to credentials sent_)
- **Environment Variables**:
- `SA_SPAM_SUBJECT` has been renamed into `SPAM_SUBJECT` to become anti-spam service agnostic. ([3820](https://github.com/docker-mailserver/docker-mailserver/pull/3820))
- As this functionality is now handled in Dovecot via a Sieve script instead of the respective anti-spam service during Postfix processing, this feature will only apply to mail stored in Dovecot. If you have relied on this feature in a different context, it will no longer be available.
@ -54,11 +69,17 @@ The most noteworthy change of this release is the update of the container's base
- Refactored helper methods for sending e-mails with specific `Message-ID` headers and the helpers for retrieving + filtering logs, which together help isolate logs relevant to specific mail when multiple mails have been processed within a single test. ([#3786](https://github.com/docker-mailserver/docker-mailserver/pull/3786))
- **Rspamd**:
- The `rewrite_subject` action, is now disabled by default. It has been replaced with the new `SPAM_SUBJECT` environment variable, which implements the functionality via a Sieve script instead in favor of being anti-spam service agnostic ([3820](https://github.com/docker-mailserver/docker-mailserver/pull/3820))
- `RSPAMD_NEURAL` was added and is disabled by default. If switched on it wil enable the experimental Rspamd Neural network module to add a layer of analysis to spam detection using neural network technology. ([3833](https://github.com/docker-mailserver/docker-mailserver/pull/3833))
### Fixes
- DMS config files that are parsed line by line are now more robust to parse by detecting and fixing line-endings ([#3819](https://github.com/docker-mailserver/docker-mailserver/pull/3819))
- Variables related to Rspamd are declared as `readonly`, which would cause warnings in the log when being re-declared; we now guard against this issue ([#3837](https://github.com/docker-mailserver/docker-mailserver/pull/3837))
- Relay host feature refactored ([#3845](https://github.com/docker-mailserver/docker-mailserver/pull/3845))
- `DEFAULT_RELAY_HOST` ENV can now also use the `RELAY_USER` + `RELAY_PASSWORD` ENV for supplying credentials.
- `RELAY_HOST` ENV no longer enforces configuring outbound SMTP to require credentials. Like `DEFAULT_RELAY_HOST` it can now configure a relay where credentials are optional.
- Restarting DMS should not be required when configuring relay hosts without these ENV, but solely via `setup relay ...`, as change detection events now apply relevant Postfix setting changes for supporting credentials too.
- Rspamd configuration: Add a missing comma in `local_networks` so that all internal IP addresses are actually considered as internal ([#3862](https://github.com/docker-mailserver/docker-mailserver/pull/3862))
## [v13.3.1](https://github.com/docker-mailserver/docker-mailserver/releases/tag/v13.3.1)

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

@ -451,6 +451,17 @@ Can be used to control the score when the [`HFILTER_HOSTNAME_UNKNOWN` symbol](#r
Default: 6 (which corresponds to the `add_header` action)
##### RSPAMD_NEURAL
Can be used to enable or disable the [Neural network module][rspamd-docs-neural-network]. This is an experimental anti-spam weigh method using three neuaral networks in the configuration added here. As far as we can tell it trains itsself by using other modules to find out what spam is. It will take a while (a week or more) to train its first neural network. The config trains new networks all the time and discards of old networks.
Since it is experimental it is switched of by default.
- **0** => Disabled
- 1 => Enabled
[rspamd-docs-neural-network]: https://www.rspamd.com/doc/modules/neural.html
#### Reports
##### PFLOGSUMM_TRIGGER
@ -1012,36 +1023,109 @@ you to replace both instead of just the envelope sender.
- **empty** => Derived from [`OVERRIDE_HOSTNAME`](#override_hostname), `$DOMAINNAME` (internal), or the container's hostname
- Set this if auto-detection fails, isn't what you want, or you wish to have a separate container handle DSNs
#### Default Relay Host
#### Relay Host
Supported ENV for the [Relay Host][docs::relay-host] feature.
!!! 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"
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
- **empty** => don't set default relayhost setting in main.cf
- default host and port to relay all mail through.
Format: `[example.com]:587` (don't forget the brackets if you need this to
be compatible with `$RELAY_USER` and `$RELAY_PASSWORD`, explained below).
Configures a default relay host.
#### Multi-domain Relay Hosts
!!! info
- All mail sent outbound from DMS will be relayed through the configured host, unless sender-dependent relayhost maps have been configured (_which have precedence_).
- The host value may optionally be wrapped in brackets (_skips DNS query for MX record_): `[mail.example.com]:587` vs `example.com:587`
!!! abstract "Technical Details"
This ENV internally configures the Postfix `main.cf` setting: [`relayhost`][postfix-config::relayhost]
##### RELAY_HOST
- **empty** => don't configure relay host
- default host to relay mail through
Configures a 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.
!!! 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"
This feature is configured internally using the:
- 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
- **empty** => 25
- default port to relay mail through
Default => 25
Support for configuring a different port than 25 for `RELAY_HOST` to use.
!!! note
Requires `RELAY_HOST`.
#### Relay Host Credentials
!!! 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
- **empty** => no default
- default relay username (if no specific entry exists in postfix-sasl-password.cf)
##### RELAY_PASSWORD
- **empty** => no default
- password for default relay user
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 risking ENV exposing secrets.
- 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"
Credentials for relay hosts are configured internally using the:
- 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`_)
---
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
@ -1049,4 +1133,8 @@ you to replace both instead of just the envelope sender.
[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
[postfix-config::sasl_passwd]: https://www.postfix.org/postconf.5.html#smtp_sasl_password_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

View File

@ -183,6 +183,12 @@ RSPAMD_HFILTER=1
# Default: 6
RSPAMD_HFILTER_HOSTNAME_UNKNOWN_SCORE=6
# Can be used to enable or disable the (still experimental) neural module.
#
# - **0** => Disabled
# - 1 => Enabled
RSPAMD_NEURAL=0
# Amavis content filter (used for ClamAV & SpamAssassin)
# 0 => Disabled
# 1 => Enabled
@ -619,8 +625,8 @@ SRS_SECRET=
# Setup relaying all mail through a default relay host
#
# empty => don't configure default relay host
# default host and optional port to relay all mail through
# Set a default host to relay all mail through (optionally include a port)
# Example: [mail.example.com]:587
DEFAULT_RELAY_HOST=
# -----------------------------------------------
@ -630,18 +636,22 @@ DEFAULT_RELAY_HOST=
# Setup relaying for multiple domains based on the domain name of the sender
# optionally uses usernames and passwords in postfix-sasl-password.cf and relay host mappings in postfix-relaymap.cf
#
# empty => don't configure relay host
# default host to relay mail through
# Set a default host to relay mail through
# Example: mail.example.com
RELAY_HOST=
# empty => 25
# default port to relay mail
RELAY_PORT=25
# -----------------------------------------------
# --- Relay Host Credentials Section ------------
# -----------------------------------------------
# Configure a relay user and password to use with RELAY_HOST / DEFAULT_RELAY_HOST
# empty => no default
# default relay username (if no specific entry exists in postfix-sasl-password.cf)
RELAY_USER=
# empty => no default
# password for default relay user
RELAY_PASSWORD=

View File

@ -0,0 +1,42 @@
#https://github.com/rspamd/rspamd/issues/3099
rules {
"NEURAL_WEEK_1000" {
train {
max_trains = 1000;
max_usages = 50;
max_iterations = 25;
learning_rate = 0.01,
spam_score = 8;
ham_score = -2;
}
symbol_spam = "NEURAL_WEEK_SPAM";
symbol_ham = "NEURAL_WEEK_HAM";
ann_expire = 300d;
}
"NEURAL_DAYS_200" {
train {
max_trains = 200;
max_usages = 10;
max_iterations = 25;
learning_rate = 0.01,
spam_score = 8;
ham_score = -2;
}
symbol_spam = "NEURAL_DAYS_SPAM";
symbol_ham = "NEURAL_DAYS_HAM";
ann_expire = 100d;
}
"NEURAL_HALF_DAY_50" {
train {
max_trains = 50;
max_usages = 4;
max_iterations = 25;
learning_rate = 0.01,
spam_score = 8;
ham_score = -2;
}
symbol_spam = "NEURAL_HALF_DAY_SPAM";
symbol_ham = "NEURAL_HALF_DAY_HAM";
ann_expire = 13d;
}
}

View File

@ -0,0 +1,26 @@
symbols = {
"NEURAL_WEEK_SPAM" {
weight = 3.0; # sample weight
description = "Neural network spam (long)";
}
"NEURAL_WEEK_HAM" {
weight = -3.0; # sample weight
description = "Neural network ham (long)";
}
"NEURAL_DAYS_SPAM" {
weight = 2.5; # sample weight
description = "Neural network spam (medium)";
}
"NEURAL_DAYS_HAM" {
weight = -1.5; # sample weight
description = "Neural network ham (medium)";
}
"NEURAL_HALF_DAY_SPAM" {
weight = 2.0; # sample weight
description = "Neural network spam (short)";
}
"NEURAL_HALF_DAY_HAM" {
weight = -1.0; # sample weight
description = "Neural network ham (short)";
}
}

View File

@ -1,3 +1,3 @@
pidfile = false;
soft_reject_on_timeout = true;
local_networks = "127.0.0.1/8, 10.0.0.0/8, 172.16.0.0/12 192.168.0.0/16";
local_networks = "127.0.0.1/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16";

View File

@ -49,17 +49,7 @@ function _check_for_changes() {
local CHANGED
CHANGED=$(_get_changed_files "${CHKSUM_FILE}" "${CHKSUM_FILE}.new")
# Handle any changes
_ssl_changes
_postfix_dovecot_changes
_rspamd_changes
_log_with_date 'debug' 'Reloading services due to detected changes'
[[ ${ENABLE_AMAVIS} -eq 1 ]] && _reload_amavis
_reload_postfix
[[ ${SMTP_ONLY} -ne 1 ]] && dovecot reload
_handle_changes
_remove_lock
_log_with_date 'debug' 'Completed handling of detected change'
@ -69,6 +59,29 @@ function _check_for_changes() {
fi
}
function _handle_changes() {
# Variable to identify any config updates dependent upon vhost changes.
local VHOST_UPDATED=0
# These two configs are the source for /etc/postfix/vhost (managed mail domains)
if [[ ${CHANGED} =~ ${DMS_DIR}/postfix-(accounts|virtual).cf ]]; then
_log_with_date 'trace' 'Regenerating vhosts (Postfix)'
# Regenerate via `helpers/postfix.sh`:
_create_postfix_vhost
VHOST_UPDATED=1
fi
_ssl_changes
_postfix_dovecot_changes
_rspamd_changes
_log_with_date 'debug' 'Reloading services due to detected changes'
[[ ${ENABLE_AMAVIS} -eq 1 ]] && _reload_amavis
_reload_postfix
[[ ${SMTP_ONLY} -ne 1 ]] && dovecot reload
}
function _get_changed_files() {
local CHKSUM_CURRENT=${1}
local CHKSUM_NEW=${2}
@ -85,9 +98,9 @@ function _get_changed_files() {
}
function _reload_amavis() {
if [[ ${CHANGED} =~ ${DMS_DIR}/postfix-accounts.cf ]] || [[ ${CHANGED} =~ ${DMS_DIR}/postfix-virtual.cf ]]; then
# /etc/postfix/vhost was updated, amavis must refresh it's config by
# reading this file again in case of new domains, otherwise they will be ignored.
# /etc/postfix/vhost was updated, amavis must refresh it's config by
# reading this file again in case of new domains, otherwise they will be ignored.
if [[ ${VHOST_UPDATED} -eq 1 ]]; then
amavisd reload
fi
}
@ -114,14 +127,12 @@ function _postfix_dovecot_changes() {
# - postfix-sasl-password.cf used by _relayhost_sasl
# - _populate_relayhost_map relies on:
# - postfix-relaymap.cf
# - postfix-accounts.cf + postfix-virtual.cf (both will be dropped in future)
if [[ ${CHANGED} =~ ${DMS_DIR}/postfix-accounts.cf ]] \
|| [[ ${CHANGED} =~ ${DMS_DIR}/postfix-virtual.cf ]] \
if [[ ${VHOST_UPDATED} -eq 1 ]] \
|| [[ ${CHANGED} =~ ${DMS_DIR}/postfix-relaymap.cf ]] \
|| [[ ${CHANGED} =~ ${DMS_DIR}/postfix-sasl-password.cf ]]
then
_log_with_date 'trace' 'Regenerating relay config (Postfix)'
_rebuild_relayhost
_process_relayhost_configs
fi
# Regenerate system + virtual account aliases via `helpers/aliases.sh`:
@ -129,14 +140,6 @@ function _postfix_dovecot_changes() {
[[ ${CHANGED} =~ ${DMS_DIR}/postfix-regexp.cf ]] && _handle_postfix_regexp_config
[[ ${CHANGED} =~ ${DMS_DIR}/postfix-aliases.cf ]] && _handle_postfix_aliases_config
# Regenerate `/etc/postfix/vhost` (managed mail domains) via `helpers/postfix.sh`:
if [[ ${CHANGED} =~ ${DMS_DIR}/postfix-accounts.cf ]] \
|| [[ ${CHANGED} =~ ${DMS_DIR}/postfix-virtual.cf ]]
then
_log_with_date 'trace' 'Regenerating vhosts (Postfix)'
_create_postfix_vhost
fi
# Legacy workaround handled here, only seems necessary for _create_accounts:
# - `helpers/accounts.sh` logic creates folders/files with wrong ownership.
_chown_var_mail_if_necessary

View File

@ -43,21 +43,28 @@ function _vhost_collect_postfix_domains() {
local DATABASE_VIRTUAL='/tmp/docker-mailserver/postfix-virtual.cf'
local DOMAIN UNAME
# getting domains FROM mail accounts
# Extract domains from mail accounts:
if [[ -f ${DATABASE_ACCOUNTS} ]]; then
while IFS=$'|' read -r LOGIN _; do
DOMAIN=$(echo "${LOGIN}" | cut -d @ -f2)
while IFS=$'|' read -r MAIL_ACCOUNT _; do
# It is expected valid lines have the format local-part@domain-part:
DOMAIN=$(cut -d '@' -f 2 <<< "${MAIL_ACCOUNT}")
echo "${DOMAIN}" >>"${TMP_VHOST}"
done < <(_get_valid_lines_from_file "${DATABASE_ACCOUNTS}")
fi
# getting domains FROM mail aliases
# TODO: Consider if virtual aliases should be configured to the same vhost file:
# https://github.com/docker-mailserver/docker-mailserver/issues/2813#issuecomment-1272394563
# Extract domains from virtual alias config:
# Aliases may have the forms: 'local-part@domain-part', only 'local-part', or '@domain-part' (wildcard catch-all)
if [[ -f ${DATABASE_VIRTUAL} ]]; then
while read -r FROM _; do
UNAME=$(echo "${FROM}" | cut -d @ -f1)
DOMAIN=$(echo "${FROM}" | cut -d @ -f2)
while read -r ALIAS_FIELD _; do
UNAME=$(cut -d '@' -f 1 <<< "${ALIAS_FIELD}")
DOMAIN=$(cut -d '@' -f 2 <<< "${ALIAS_FIELD}")
# if they are equal it means the line looks like: "user1 other@domain.tld"
# Only add valid domain-parts found:
# The '@' is optional for an alias key (eg: "user1 other@domain.tld"),
# but cut with -f2 would output the same value as it would -f1 when '@' is missing.
[[ ${UNAME} != "${DOMAIN}" ]] && echo "${DOMAIN}" >>"${TMP_VHOST}"
done < <(_get_valid_lines_from_file "${DATABASE_VIRTUAL}")
fi

View File

@ -4,9 +4,9 @@
# Description:
# This helper is responsible for configuring outbound SMTP (delivery) through relay-hosts.
#
# When mail is sent from Postfix, it is considered relaying to that destination (or the next hop).
# By default delivery external of the container would be direct to the MTA of the recipient address (destination).
# Alternatively mail can be indirectly delivered to the destination by routing through a different MTA (relay-host service).
# When mail is sent to Postfix and the destination is not a domain DMS manages, this requires relaying to that destination (or the next hop).
# By default outbound mail delivery would be direct to the MTA of the recipient address (destination).
# Alternatively mail can be delivered indirectly to that destination by routing through a different MTA (relay-host service).
#
# This helper is only concerned with relaying mail from authenticated submission (ports 587 + 465).
# Thus it does not deal with `relay_domains` (which routes through `relay_transport` transport, default: `master.cf:relay`),
@ -37,22 +37,23 @@
# `postfix reload` or `supervisorctl restart postfix` should be run to properly apply config (which it is).
# Otherwise use another table type such as `hash` and run `postmap` on the table after modification.
#
# WARNING: Databases (tables above) are rebuilt during change detection. There is a minor chance of
# a lookup occurring during a rebuild of these files that may affect or delay delivery?
# WARNING: Databases (tables above) are rebuilt during change detection.
# There is a minor chance of a lookup occurring during a rebuild of these files that may affect or delay delivery?
# TODO: Should instead perform an atomic operation with a temporary file + `mv` to replace?
# Or switch back to using `hash` table type if plaintext access is not needed (unless retaining file for postmap).
# Either way, plaintext copy is likely accessible if using our supported configs for providing them to the container.
# NOTE: Present support has enforced wrapping the relay host with `[]` (prevents DNS MX record lookup),
# which restricts what is supported by RELAY_HOST, although you usually do want to provide MX host directly.
# NOTE: Present support expects to always append a port with an implicit default of `25`.
# NOTE: DEFAULT_RELAY_HOST imposes neither restriction.
# NOTE: Present support has enforced wrapping the `RELAY_HOST` value with `[]` (prevents DNS MX record lookup),
# shouldn't be an issue as you typically do want to provide the MX host directly? This was presumably for config convenience.
# NOTE: Present support expects to always append a port (_with an implicit default of `25`_).
# NOTE: The `DEFAULT_RELAY_HOST` ENV imposes neither restriction.
#
# TODO: RELAY_PORT should be optional, it will use the transport default port (`postconf smtp_tcp_port`),
# TODO: `RELAY_PORT` should be optional (Postfix would fallback to the transports default port (`postconf smtp_tcp_port`),
# That shouldn't be a breaking change, as long as the mapping is maintained correctly.
# TODO: RELAY_HOST should consider dropping `[]` and require the user to include that?
# Future refactor for _populate_relayhost_map may warrant dropping these two ENV in favor of DEFAULT_RELAY_HOST?
# TODO: `RELAY_HOST` should consider dropping the implicit `[]` and require the user to include that?
#
# A future refactor of `_populate_relayhost_map()` may warrant dropping those two ENV in favor of `DEFAULT_RELAY_HOST`?
function _env_relay_host() {
echo "[${RELAY_HOST}]:${RELAY_PORT:-25}"
}
@ -60,10 +61,12 @@ function _env_relay_host() {
# Responsible for `postfix-sasl-password.cf` support:
# `/etc/postfix/sasl_passwd` example at end of file.
function _relayhost_sasl() {
if [[ ! -f /tmp/docker-mailserver/postfix-sasl-password.cf ]] \
&& [[ -z ${RELAY_USER} || -z ${RELAY_PASSWORD} ]]
then
_log 'warn' "Missing relay-host mapped credentials provided via ENV, or from postfix-sasl-password.cf"
local DATABASE_SASL_PASSWD='/tmp/docker-mailserver/postfix-sasl-password.cf'
# Only relevant when required credential sources are provided:
if [[ ! -f ${DATABASE_SASL_PASSWD} ]] \
&& [[ -z ${RELAY_USER} || -z ${RELAY_PASSWORD} ]]; then
_log 'warn' "Missing relay-host mapped credentials provided via ENV, or from ${DATABASE_SASL_PASSWD}"
return 1
fi
@ -74,7 +77,6 @@ function _relayhost_sasl() {
chown root:root /etc/postfix/sasl_passwd
chmod 0600 /etc/postfix/sasl_passwd
local DATABASE_SASL_PASSWD='/tmp/docker-mailserver/postfix-sasl-password.cf'
if [[ -f ${DATABASE_SASL_PASSWD} ]]; then
# Add domain-specific auth from config file:
_get_valid_lines_from_file "${DATABASE_SASL_PASSWD}" >> /etc/postfix/sasl_passwd
@ -83,90 +85,93 @@ function _relayhost_sasl() {
postconf 'smtp_sender_dependent_authentication = yes'
fi
# Add an authenticated relay host defined via ENV config:
if [[ -n ${RELAY_USER} ]] && [[ -n ${RELAY_PASSWORD} ]]; then
echo "$(_env_relay_host) ${RELAY_USER}:${RELAY_PASSWORD}" >> /etc/postfix/sasl_passwd
# Support authentication to a primary relayhost (when configured with credentials via ENV):
if [[ -n ${DEFAULT_RELAY_HOST} || -n ${RELAY_HOST} ]] \
&& [[ -n ${RELAY_USER} && -n ${RELAY_PASSWORD} ]]; then
echo "${DEFAULT_RELAY_HOST:-$(_env_relay_host)} ${RELAY_USER}:${RELAY_PASSWORD}" >>/etc/postfix/sasl_passwd
fi
# Technically if only a single relay host is configured, a `static` lookup table could be used instead?:
# postconf "smtp_sasl_password_maps = static:${RELAY_USER}:${RELAY_PASSWORD}"
postconf 'smtp_sasl_password_maps = texthash:/etc/postfix/sasl_passwd'
# Enable credential lookup + SASL authentication to relayhost:
# - `noanonymous` enforces authentication requirement
# - `encrypt` enforces requirement for a secure connection (prevents sending credentials over cleartext, aka mandatory TLS)
postconf \
'smtp_sasl_password_maps = texthash:/etc/postfix/sasl_passwd' \
'smtp_sasl_auth_enable = yes' \
'smtp_sasl_security_options = noanonymous' \
'smtp_tls_security_level = encrypt'
}
# Responsible for `postfix-relaymap.cf` support:
# `/etc/postfix/relayhost_map` example at end of file.
#
# Present support uses a table lookup for sender address or domain mapping to relay-hosts,
# Populated via `postfix-relaymap.cf `, which also features a non-standard way to exclude implicitly added internal domains from the feature.
# It also maps all known sender domains (from configs postfix-accounts + postfix-virtual.cf) to the same ENV configured relay-host.
# `postfix-relaymap.cf` represents table syntax expected for `/etc/postfix/relayhost_map`, except that it adds an opt-out parsing feature.
# All known mail domains managed by DMS (/etc/postfix/vhost) are implicitly configured to use `RELAY_HOST` + `RELAY_PORT` as the default relay.
# This approach is effectively equivalent to using `main.cf:relayhost`, but with an excessive workaround to support the explicit opt-out feature.
#
# TODO: The account + virtual config parsing and appending to /etc/postfix/relayhost_map seems to be an excessive `main.cf:relayhost`
# implementation, rather than leveraging that for the same purpose and selectively overriding only when needed with `/etc/postfix/relayhost_map`.
# If the issue was to opt-out select domains, if avoiding a default relay-host was not an option, then mapping those sender domains or addresses
# to a separate transport (which can drop the `relayhost` setting) would be more appropriate.
# TODO: With `sender_dependent_default_transport_maps`, we can extract out the excluded domains and route them through a separate transport.
# while deprecating that support in favor of a transport config, similar to what is offered currently via sasl_passwd and relayhost_map.
# TODO: Refactor this feature support so that in `main.cf`:
# - Relay all outbound mail through an external MTA by default (works without credentials):
# `relayhost = ${DEFAULT_RELAY_HOST}`
# - Opt-in to relaying - Selectively relay outbound mail by sender/domain to an external MTA (relayhost can vary):
# `sender_dependent_relayhost_maps = texthash:/etc/postfix/relayhost_map`
# - Opt-out from relaying - Selectively prevent outbound mail from relaying via separate transport mappings (where relayhost is not configured):
# By sender: `sender_dependent_default_transport_maps = texthash:/etc/postfix/sender_transport_map` (the current opt-out feature could utilize this instead)
# By recipient (has precedence): `transport_maps = texthash:/etc/postfix/recipient_transport_map`
#
# Support for relaying via port 465 or equivalent requires additional config support (as needed for 465 vs 587 transports extending smtpd)
# - Default relay transport is configured by `relay_transport`, with default transport port configured by `smtp_tcp_port`.
# - The `relay` transport itself extends from `smtp` transport. More than one can be configured with separate settings via `master.cf`.
function _populate_relayhost_map() {
# Create the relayhost_map config file:
: >/etc/postfix/relayhost_map
chown root:root /etc/postfix/relayhost_map
chmod 0600 /etc/postfix/relayhost_map
# Matches lines that are not comments or only white-space:
local MATCH_VALID='^\s*[^#[:space:]]'
# This config is mostly compatible with `/etc/postfix/relayhost_map`, but additionally supports
# not providing a relay host for a sender domain to opt-out of RELAY_HOST? (2nd half of function)
if [[ -f /tmp/docker-mailserver/postfix-relaymap.cf ]]; then
_log 'trace' "Adding relay mappings from postfix-relaymap.cf"
# Match two values with some white-space between them (eg: `@example.test [relay.service.test]:465`):
local MATCH_VALUE_PAIR='\S*\s+\S'
# Copy over lines which are not a comment *and* have a destination.
sed -n -r "/${MATCH_VALID}${MATCH_VALUE_PAIR}/p" /tmp/docker-mailserver/postfix-relaymap.cf >>/etc/postfix/relayhost_map
fi
# Everything below here is to parse `postfix-accounts.cf` and `postfix-virtual.cf`,
# extracting out the domain parts (value of email address after `@`), and then
# adding those as mappings to ENV configured RELAY_HOST for lookup in `/etc/postfix/relayhost_map`.
# Provided `postfix-relaymap.cf` didn't exclude any of the domains,
# and they don't already exist within `/etc/postfix/relayhost_map`.
#
# TODO: Breaking change. Replace this lower half and remove the opt-out feature from `postfix-relaymap.cf`.
# Leverage `main.cf:relayhost` for setting a default relayhost as it was prior to this feature addition.
# Any sender domains or addresses that need to opt-out of that default relay-host can either
# map to a different relay-host, or use a separate transport (needs feature support added).
# Args: <PRINT_DOMAIN_PART_> <config filepath>
function _list_domain_parts() {
[[ -f $2 ]] && sed -n -r "/${MATCH_VALID}/ ${1}" "${2}"
}
# Matches and outputs (capture group via `/\1/p`) the domain part (value of address after `@`) in the config file.
local PRINT_DOMAIN_PART_ACCOUNTS='s/^[^@|]*@([^\|]+)\|.*$/\1/p'
local PRINT_DOMAIN_PART_VIRTUAL='s/^\s*[^@[:space:]]*@(\S+)\s.*/\1/p'
{
_list_domain_parts "${PRINT_DOMAIN_PART_ACCOUNTS}" /tmp/docker-mailserver/postfix-accounts.cf
_list_domain_parts "${PRINT_DOMAIN_PART_VIRTUAL}" /tmp/docker-mailserver/postfix-virtual.cf
} | sort -u | while read -r DOMAIN_PART; do
# DOMAIN_PART not already present in `/etc/postfix/relayhost_map`, and not listed as a relay opt-out domain in `postfix-relaymap.cf`
# `^@${DOMAIN_PART}\b` - To check for existing entry, the `\b` avoids accidental partial matches on similar domain parts.
# `^\s*@${DOMAIN_PART}\s*$` - Matches line with only a domain part (eg: @example.test) to avoid including a mapping for those domains to the RELAY_HOST.
if ! grep -q -e "^@${DOMAIN_PART}\b" /etc/postfix/relayhost_map && ! grep -qs -e "^\s*@${DOMAIN_PART}\s*$" /tmp/docker-mailserver/postfix-relaymap.cf; then
_log 'trace' "Adding relay mapping for ${DOMAIN_PART}"
echo "@${DOMAIN_PART} $(_env_relay_host)" >> /etc/postfix/relayhost_map
fi
done
_multiple_relayhosts
_legacy_support
postconf 'sender_dependent_relayhost_maps = texthash:/etc/postfix/relayhost_map'
}
function _relayhost_configure_postfix() {
postconf \
'smtp_sasl_auth_enable = yes' \
'smtp_sasl_security_options = noanonymous' \
'smtp_tls_security_level = encrypt'
function _multiple_relayhosts() {
if [[ -f ${DATABASE_RELAYHOSTS} ]]; then
_log 'trace' "Adding relay mappings from ${DATABASE_RELAYHOSTS}"
# Matches lines that are not comments or only white-space:
local MATCH_VALID='^\s*[^#[:space:]]'
# Match two values with some white-space between them (eg: `@example.test [relay.service.test]:465`):
local MATCH_VALUE_PAIR='\S*\s+\S'
# Copy over lines which are not a comment *and* have a relay destination.
# Extra condition is due to legacy support (due to opt-out feature), otherwise `_get_valid_lines_from_file()` would be valid.
sed -n -r "/${MATCH_VALID}${MATCH_VALUE_PAIR}/p" "${DATABASE_RELAYHOSTS}" >> /etc/postfix/relayhost_map
fi
}
# Implicitly force configure all domains DMS manages to be relayed that haven't yet been configured or provided an explicit opt-out.
# This would normally be handled via an opt-in approach, or through `main.cf:relayhost` with an opt-out approach (sender_dependent_default_transport_maps)
function _legacy_support() {
local DATABASE_VHOST='/etc/postfix/vhost'
# Only relevant when `RELAY_HOST` is configured:
[[ -z ${RELAY_HOST} ]] && return 1
# Configures each `SENDER_DOMAIN` to send outbound mail through the default `RELAY_HOST` + `RELAY_PORT`
# (by adding an entry in `/etc/postfix/relayhost_map`) provided it:
# - `/etc/postfix/relayhost_map` doesn't already have it as an existing entry.
# - `postfix-relaymap.cf` has no explicit opt-out (SENDER_DOMAIN key exists, but with no relayhost value assigned)
#
# NOTE: /etc/postfix/vhost represents managed mail domains sourced from `postfix-accounts.cf` and `postfix-virtual.cf`.
while read -r SENDER_DOMAIN; do
local MATCH_EXISTING_ENTRY="^@${SENDER_DOMAIN}\s+"
local MATCH_OPT_OUT_LINE="^\s*@${SENDER_DOMAIN}\s*$"
# NOTE: `-E` is required for `\s+` syntax to avoid escaping `+`
if ! grep -q -E "${MATCH_EXISTING_ENTRY}" /etc/postfix/relayhost_map && ! grep -qs "${MATCH_OPT_OUT_LINE}" "${DATABASE_RELAYHOSTS}"; then
_log 'trace' "Configuring '${SENDER_DOMAIN}' for the default relayhost '${RELAY_HOST}'"
echo "@${SENDER_DOMAIN} $(_env_relay_host)" >> /etc/postfix/relayhost_map
fi
done < <(_get_valid_lines_from_file "${DATABASE_VHOST}")
}
function _setup_relayhost() {
@ -177,23 +182,23 @@ function _setup_relayhost() {
postconf "relayhost = ${DEFAULT_RELAY_HOST}"
fi
if [[ -n ${RELAY_HOST} ]]; then
_log 'trace' "Setting up relay hosts (default: ${RELAY_HOST})"
_relayhost_sasl
_populate_relayhost_map
_relayhost_configure_postfix
fi
_process_relayhost_configs
}
function _rebuild_relayhost() {
if [[ -n ${RELAY_HOST} ]]; then
_relayhost_sasl
_populate_relayhost_map
fi
}
# Called during initial container setup, or by change detection event:
function _process_relayhost_configs() {
local DATABASE_RELAYHOSTS='/tmp/docker-mailserver/postfix-relaymap.cf'
# One of these must configure a relayhost for the feature to relevant:
if [[ ! -f ${DATABASE_RELAYHOSTS} ]] \
&& [[ -z ${DEFAULT_RELAY_HOST} ]] \
&& [[ -z ${RELAY_HOST} ]]; then
return 1
fi
_relayhost_sasl
_populate_relayhost_map
}
#
# Config examples for reference

View File

@ -20,6 +20,7 @@ function _setup_rspamd() {
__rspamd__setup_learning
__rspamd__setup_greylisting
__rspamd__setup_hfilter_group
__rspamd__setup_neural
__rspamd__setup_check_authenticated
_rspamd_handle_user_modules_adjustments # must run last
@ -186,7 +187,6 @@ function __rspamd__setup_default_modules() {
local DISABLE_MODULES=(
clickhouse
elastic
neural
reputation
spamassassin
url_redirector
@ -283,6 +283,23 @@ function __rspamd__setup_hfilter_group() {
fi
}
# This function handles setup of the neural module (see
# https://www.rspamd.com/doc/modules/neural.html). This module is experimental
# but can enhance anti-spam scoring possibly.
function __rspamd__setup_neural() {
if _env_var_expect_zero_or_one 'RSPAMD_NEURAL' && [[ ${RSPAMD_NEURAL} -eq 1 ]]; then
__rspamd__log 'debug' 'Enabling Neural module'
__rspamd__log 'warn' 'The Neural module is still experimental (in Rspamd) and hence not tested in DMS'
else
__rspamd__log 'debug' 'Neural module is disabled'
rm -f "${RSPAMD_LOCAL_D}/neural.conf"
rm -f "${RSPAMD_LOCAL_D}/neural_group.conf"
__rspamd__helper__enable_disable_module 'neural' 'false'
fi
}
# If 'RSPAMD_CHECK_AUTHENTICATED' is enabled, then content checks for all users, i.e.
# also for authenticated users, are performed.
#

View File

@ -71,6 +71,7 @@ function __environment_variables_general_setup() {
VARS[RSPAMD_GREYLISTING]="${RSPAMD_GREYLISTING:=0}"
VARS[RSPAMD_HFILTER]="${RSPAMD_HFILTER:=1}"
VARS[RSPAMD_HFILTER_HOSTNAME_UNKNOWN_SCORE]="${RSPAMD_HFILTER_HOSTNAME_UNKNOWN_SCORE:=6}"
VARS[RSPAMD_NEURAL]="${RSPAMD_NEURAL:=0}"
VARS[RSPAMD_LEARN]="${RSPAMD_LEARN:=0}"
VARS[SA_KILL]=${SA_KILL:="10.0"}
VARS[SPAM_SUBJECT]=${SPAM_SUBJECT:=}