Skip to content

refactor: Revised relay.sh helper#2604

Merged
polarathene merged 10 commits intodocker-mailserver:masterfrom
polarathene:refactor/relay-support
Jun 4, 2022
Merged

refactor: Revised relay.sh helper#2604
polarathene merged 10 commits intodocker-mailserver:masterfrom
polarathene:refactor/relay-support

Conversation

@polarathene
Copy link
Copy Markdown
Member

@polarathene polarathene commented May 29, 2022

Description

This is a refactor of the current relay support offered via docker-mailserver. For the most part, this is preparation for a future PR that will make some breaking changes to revise the relay support offered. I want to simplify review for that by covering the changes here.

Reviewers that are not familiar with present relay support should have no trouble getting up to speed. Supporting comments can be dropped before merge or via follow-up commit if necessary. Changes have been staged out into separate commits (with their own commit messages for context) should that assist with review.

I also have a related change with SASL_PASSWD support that would have added noise to the review here. I've opted to cherry-pick it out of this PR and into it's own PR that will follow upon merging of this PR. (EDIT: PR opened, will be rebased after merging this one)

Overview of changes (ordered by appearance in relay.sh)

  • Inline docs heavily revised. Any maintainer touching relay support should easily be aware of associated content in the project to this feature that helpers/relay.sh manages.
  • _relayhost_default_port_fallback() has been dropped. It no longer serves a purpose.
  • _env_relay_host() has been added. It provides the default port fallback and ensures the configured relay-host is in sync between both /etc/postfix/sasl_passwd and /etc/postfix/relayhost_map, which is required for successful lookup.
  • Config examples revised and shifted to the end of the document due to size. Additional supporting information for maintainers to be aware of included. Likely to be relocated in future to a "maintainers" section of our docs as historically some maintainers have removed contextual information (eg: the Dockerfile used to better document some layers).
  • Some main.cf settings configured via postconf have been relocated from _relayhost_configure_postfix() to their relevant sections of code. There may be potential risk of breakage in a deployment that relied on those being set regardless when RELAY_HOST ENV was set, but did not leverage our feature support that specifically requires them (and for which they were originally added for). It is intended in future to manage separate transports beyond the present default master.cf:smtp one.
  • _populate_relayhost_map should function the same. The changes are mostly to make it's purpose and concerns for changes in future clear (normally I keep notes locally instead of inlining, but have chosen to make sure others can understand the feature quickly and what changes need to be done should future work lag behind on my part, someone else could pick it up). Plan is to better implement the features intent without the excessive approach with accounts currently used.
  • _relayhost_configure_postfix() is simplified. Some settings configured there were unnecessary, see associated commit for details. In future a separate SMTP client transport will be configured, which will better support the use-cases from past relay-host contributions and more easily allow for supporting multiple relay-hosts with different requirements (no auth, explicit TLS, implicit TLS, varying ports).

Relay-host feature history:

I went through the history of the feature to understand why decisions for current support exist, use-cases and if any breakage may be an issue (especially around SASL_PASSWD and why that path looked borked).

Documenting that history here for others, which may be helpful to maintainers in future rather than trawling git blame 😅

  • Original relay support introduced in Feb 2016 (#83):
    • Introduced main.cf customization via user config file (postfix-main.cf).
    • Introduced SASL_PASSWD ENV to automate creating a hash table (the generated .db file received chown/chmod adjustments, then temporary input file removed) as opposed to using plaintext with the static table type in the main.cf setting.
    • Introduced smtp_tls_security_level=none to amavis transports. smtp_tls_wrappermode=no was probably not set as port 465 was not as relevant in 2016.
  • May 2016 expanded support for AWS SES (#194):
    • Simplified relay configuration via alternative ENV, but was intended with AWS SES in mind. It provided the required main.cf default settings for configuring an authenticated relay-host, instead of expecting the user to know what to add with a postfix-main.cf themselves. It was initially hard-coded to port 25, but future PRs resolved that.
    • smtp_sasl_password_maps was only enabled as part of this automated config. The prior SASL_PASSWD ENV support was very basic and did not include even that.
    • smtp_tls_CAfile was also introduced for relay configs via this PR. A July 2016 PR introduced smtp_tls_CApath as a default (#243), making the relay specific one redundant.
  • A Nov 2016 PR changed the table types used from hash to texthash (#382).
  • April 2018 expands support for multiple relays and credentials (#926):
    • Use cases requested here (#922).
    • The bulk of relay tests were introduced in this PR.
    • This is also where relay code was duplicated over into check-for-changes.sh.
    • RELAY_HOST and related ENV were added, replacing earlier ENV for AWS SES (despite the ENV name, was supporting other relays).
    • Introduced the setup.sh relay commands.
    • Introduced postfix-relayhost.cf and postfix-sasl-password.cf files to support multiple per sender relay-hosts and/or credentials.
    • At the same time, it dropped configuring main.cf:relayhost in favor of adopting sender dependent mappings. This seemed unnecessary, as it would append all domains from postfix-accounts.cf by default, effectively mimicking main.cf:relayhost anyway.. Presumably this was to provide support to opt-out a domain via postix-relayhost.cf, but what they'd actually want really would be to opt-in such a domain to a separate outbound transport (a future PR will introduce this and bring back main.cf:relayhost).
  • Jan 2019 added DEFAULT_RELAY_HOST to support default relay without authentication (#1104):
    • As existing relay support was enforcing that if using RELAY_HOST. This would also be addressed with the future relay-host refactor.
  • Aug 2020 refactored relay support a bit, and included virtual domains into the default RELAY_HOST per sender mapping support (#1596):
    • Introduced the _populate_relayhost_map function to try sync some of the duplicated code that wasn't complete in the earlier copy added to the change detector script.
  • An Oct 2021 refactor addressed concern with duplicate relay code falling out of sync and extracted out to the current form of a relay.sh helper (#2260):
    • This was by me. It should not have changed anything other than better organizing the feature support and merging back into a central location instead of two copies.

Type of change

  • Improvement (non-breaking change that does improve existing functionality)
  • Breaking change (Potentially with postconf settings relocation)

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • New and existing unit tests pass locally with my changes

Changes to `sed` handling that made it quicker to grok, and thus easier for maintainers like myself:
- Switched regex to [extended regex](https://www.gnu.org/software/sed/manual/html_node/Extended-regexps.html).
- Extracted `sed` patterns to be self-descriptive local vars.
- Used a function to reduce noise from intent of loop input (each line as `DOMAIN_PART`).

Input for the loop is filtered through `sort -u` to drop duplicates, reducing iterations.
 
`DOMAIN` loop var renamed to less vague `DOMAIN_PART`. Additional comment in the containing method clarifies what the domain part refers to.

---

`|` regexp syntax needed to be escaped due to switch. Not documented in the earlier link. `-r`/`-E` (ERE) aka extended regexp syntax is [detailed here](https://learnbyexample.github.io/learn_gnused/breere-regular-expressions.html#cheatsheet-and-summary).
`smtp_tls_note_starttls_offer = yes` - Only adds a log entry to let you know when an unencrypted connection was made, but STARTTLS was offered:
https://www.postfix.org/postconf.5.html#smtp_tls_note_starttls_offer

`smtp_tls_CAfile` is unnecessary. This was added before `smtp_tls_CApath = /etc/ssl/certs` was several months later via a separate PR.
These have been shifted to relevant logic for now.

---

NOTE: `SASL_PASSWD` previously needed to define `RELAY_HOST` to set `smtp_sasl_password_maps` to enable the `/etc/postfix/sasl_passwd` table. This change now additionally blocks early on in `_relayhost_sasl`. Not likely important due to `RELAY_HOST` logic, user should be using the `RELAY_USER` + `RELAY_PASSWORD` ENV or `postfix-sasl-password.cf` instead.

Especially the sender dependent parameters which are only relevant with user provided configs really.

`SASL_PASSWD` is the oldest ENV for relay support before any other relay feature arrived. It is poorly documented and should not be used.

Potential breakage risk considered acceptable.
Further clarifying current processing logic and adding some additional notes for future work.
The mapping should be in sync between the two configs.

I also wanted to raise awareness of current state of support, which will likely need some refactoring.

This also removes the need for the `RELAY_PORT` fallback method.

The log message was adjusted as configuration is potentially for more than one relay host beyond the currently required ENV config to enable support.

---

NOTE: The ENV `DEFAULT_RELAY_HOST` skips modifying the default transport for an authenticated relay (locked behind `RELAY_HOST` to activate). It presently will only relay mail through a relay host on port 25 instead of delivering directly to the destination. A separate use-case.
More verbose example configs with expanded documentation.

Additional doc references for SASL support and cautioning maintainers that may reference popular relay service providers docs. May later be migrated to a "maintainers" section in official docs and link to that.

Brief overview description of what `_populate_relayhost_map` is doing.
`_populate_relayhost_map` will get some refactoring in future and likely introduce some breaking changes for a future major release.
This helper now includes a description of it's purpose, links to relevant user docs and supported `setup.sh` commands.

Intent is to keep a maintainer of the feature aware of anything relevant to this feature.
@polarathene polarathene added priority/high service/postfix area/scripts area/features kind/improvement Improve an existing feature, configuration file or the documentation labels May 29, 2022
@polarathene polarathene added this to the v11.1.0 milestone May 29, 2022
@polarathene polarathene self-assigned this May 29, 2022
Comment thread target/scripts/helpers/relay.sh
Comment thread target/scripts/helpers/relay.sh Outdated
Copy link
Copy Markdown
Member

@georglauterbach georglauterbach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍🏼

Very nice with the comments you added to the code :D

Co-authored-by: Georg Lauterbach <[email protected]>
@polarathene polarathene requested a review from a team June 4, 2022 04:14
Copy link
Copy Markdown
Member

@casperklein casperklein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 for the extended comments.

@polarathene polarathene merged commit 598aee1 into docker-mailserver:master Jun 4, 2022
@polarathene polarathene mentioned this pull request Jan 28, 2024
11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/features area/scripts kind/improvement Improve an existing feature, configuration file or the documentation priority/high service/postfix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants