Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Postfix permit DSN (Delivery Status Notification) only on authenticated ports (465 + 587) #3572

Merged
merged 8 commits into from
Oct 22, 2023

Conversation

allddd
Copy link
Contributor

@allddd allddd commented Oct 7, 2023

Description

Checking the Postifx configuration, I noticed that there were no settings related to DSN.
In my opinion, it is always a good idea to partially disable this, as it can have some unexpected (negative) effects.

What I mean by partial disabling is disabling it on port 25, which will stop incoming email from requesting a DSN.
If the server simply sends such notifications/emails to anyone who requests them, this can easily be abused and redirected to any email address by spoofing.
Even if the intention was not to send email back to the spoofed address and it was just normal spam, the backscatter can have an impact on reputation.

I have also noticed that such emails sent from a DMS instance reveal a little too much information.
For example, my tests showed that the email leaked whether an email address was an alias or not, as well as some of the software used on the server.

To ensure that this option works as intended, I have implemented some additional tests.
Apart from that, to make sure it wasn't interfering with anything else, I re-ran all the tests with POSTFIX_DSN=0, 1 and 2 as the default options.
This and manual testing showed no issues.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Improvement (non-breaking change that does improve existing functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

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
  • I have made corresponding changes to the documentation (README.md or the documentation under docs/)
  • If necessary I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Copy link
Member

@polarathene polarathene left a comment

Choose a reason for hiding this comment

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

Thanks for spotting this issue and contributing a fix 😁 (and with tests! 🥳 )

You can address the feedback or wait for input from other maintainers which might approve of dropping the ENV.

Would it make sense to restrict to authenticated by default for v13? @casperklein @georglauterbach


If there is little concern for switching to this as default, we can probably drop the need for supporting an ENV with docs, (test is still relevant). Assuming the need to adjust the setting is niche, it should be supported well via our postfix-master.cf / postfix-main.cf overrides support, should anyone raise an issue about it that could be added to a FAQ entry?

Dockerfile Outdated
@@ -201,7 +201,7 @@ RUN echo 'Reason_Message = Message {rejectdefer} due to: {spf}.' >>/etc/postfix-

COPY target/fetchmail/fetchmailrc /etc/fetchmailrc_general
COPY target/getmail/getmailrc /etc/getmailrc_general
COPY target/postfix/main.cf target/postfix/master.cf /etc/postfix/
COPY target/postfix/main.cf target/postfix/master.cf target/postfix/esmtp_access /etc/postfix/
Copy link
Member

Choose a reason for hiding this comment

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

Optional

If this config file is kept, append the .cidr suffix. Convention for postfix tables in this project that we supply appears to use the table type as the suffix?

Although for LDAP it is presently .cf 😕so I'd be fine with a common .cf too.


I know that an extension isn't required for the file, and it's fine to justify avoiding one.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Of course, as you say, the change is only visual.
My idea was to use the same name as it's called in the Postfix documentation.

Copy link
Member

Choose a reason for hiding this comment

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

Good point; I'd like to see the .cidr suffix as well :)

mailserver.env Outdated Show resolved Hide resolved
target/postfix/esmtp_access Outdated Show resolved Hide resolved
target/scripts/startup/setup.d/postfix.sh Outdated Show resolved Hide resolved
EHLO mail
AUTH PLAIN YWRkZWRAbG9jYWxob3N0LmxvY2FsZG9tYWluAGFkZGVkQGxvY2FsaG9zdC5sb2NhbGRvbWFpbgBteXBhc3N3b3Jk
MAIL FROM: added@localhost.localdomain
RCPT TO: user1@localhost.localdomain NOTIFY=success,failure
Copy link
Member

Choose a reason for hiding this comment

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

Am I right to understand the difference from regular authenticated / unauthenticated templates is effectively only the NOTIFY=success,failure addition?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, NOTIFY=... should be the only difference here.

Comment on lines 21 to 23
_run_in_container setup email add 'added@localhost.localdomain' 'mypassword'
assert_success
_wait_until_change_detection_event_completes
Copy link
Member

Choose a reason for hiding this comment

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

Just so you're aware, the tests should provide some default accounts already setup, you could simplify here by using the account there for authenticating with.

That'd remove hte need for the change-detection helper too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, thank you very much, if only I had found it sooner.
I was unaware of any users other than user1.

@polarathene
Copy link
Member

polarathene commented Oct 8, 2023

Reference

Postfix docs on DSN support:

Delivery Status Notifications as described in RFC 3464. This gives senders control over successful and failed delivery notifications.

  • Just like reports of undeliverable mail, DSN reports of successful delivery can give away more information about the internal infrastructure than desirable.
  • Unfortunately, disallowing "success" notification requests requires disallowing other DSN requests as well. The RFCs do not offer the option to negotiate feature subsets.
  • This is not as bad as it sounds.
  • When you turn off DSN for remote inbound mail, remote senders with DSN support will still be informed that their mail reached your Postfix gateway successfully; they just will not get successful delivery notices from your internal systems.
  • Remote senders lose very little: they can no longer specify how Postfix should report delayed or failed delivery.

smtpd_discard_ehlo_keywords setting:

  • A case insensitive list of EHLO keywords (pipelining, starttls, auth, etc.) that the Postfix SMTP server will not send in the EHLO response to a remote SMTP client.
  • Specify the silent-discard pseudo keyword to prevent this action from being logged.

DSN backscatter article 2017:

  • Delivery status notification (DSN), widely known as bounces, inform the sender about emails that could not be delivered or are stuck in the mail queue. In RFC 3464 DSNs have been extended in that the sender can now request information about the delivery of their mails, including successful delivery. While this may be a nice idea, it makes generating backscatter trivial.
  • Spammers only need to send an email to a valid user of your mail server, set a certain sender address and request a DSN. Your server will happily send a confirmation to that sender address. Your server generates backscatter.
  • To avoid this, DSN should not be offered to foreign users/servers. The fact that the email was received by your server should be sufficient information for the sender requesting DSN.
  • But you may want to allow your own (authenticated) users to still use DSN. To achieve this, the option can be restricted to mails received via port 25 by not adding it to main.cf but master.cf instead

DSN backscatter article 2020:

  • Checking my own mail logs, the DSN is a virtually unused feature. So it’s probably just something spammers can take advantage of.
  • Turning off DSN is often recommended against in different sendmail guides, because it’s considered a “valuable feature” or so. As mentioned above, I haven’t seen it used by anyone else than spammers.
  • FAILURE doesn’t include the user not being known to the server, in which case the message is dropped anyhow without any DSN message generated. So as a spam trick, one can’t send mails to random addresses, and issue spam bounce messages because they failed.

Postfix docs on Backscatter briefly cite a DSN issue with Outlook 2003.

Microsoft 365 docs on DSNs:

  • When there's a problem delivering an email message that you sent, Microsoft 365 or Office 365 will generate an error code and often will send an email to let you know.
  • The email you receive is a delivery status notification, also known as a DSN or Bounce Message.
  • The most common type is called a non-delivery report (NDR) and they tell you that a message wasn't delivered.
  • Non-delivery can be caused by something as simple as a typo in an email address. NDRs include an error code that indicates why your email wasn't delivered

Related DSN RFCs for reference:

@allddd

This comment was marked as resolved.

@polarathene

This comment was marked as resolved.

@allddd

This comment was marked as resolved.

@polarathene
Copy link
Member

Could either @casperklein or @georglauterbach chime in (or express an intention to when time permits), to provide your input for this contribution please?

My review notes where your opinion is requested. If no activity is received in a weeks time from either of you, I'll assume you trust me to make the call myself so that the contributor can address the feedback and the PR can be merged.

Copy link
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.

Very nice PR! Just a few touchups here and there. I mostly agree with @polarathene on the changes and added some feedback.

I highly appreciate the effort, and this is something we definitely need to take care of (since it may impact security).


I have only limited time to spare on this; I hope you excuse my superficial review. I trust @polarathene 100% with this PR though, so you needn't wait for my review to merge this PR after feedback has been applied.

Dockerfile Outdated
@@ -201,7 +201,7 @@ RUN echo 'Reason_Message = Message {rejectdefer} due to: {spf}.' >>/etc/postfix-

COPY target/fetchmail/fetchmailrc /etc/fetchmailrc_general
COPY target/getmail/getmailrc /etc/getmailrc_general
COPY target/postfix/main.cf target/postfix/master.cf /etc/postfix/
COPY target/postfix/main.cf target/postfix/master.cf target/postfix/esmtp_access /etc/postfix/
Copy link
Member

Choose a reason for hiding this comment

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

Good point; I'd like to see the .cidr suffix as well :)

target/scripts/startup/setup.d/postfix.sh Outdated Show resolved Hide resolved
mailserver.env Outdated Show resolved Hide resolved
target/postfix/esmtp_access Outdated Show resolved Hide resolved
Copy link
Member

@polarathene polarathene left a comment

Choose a reason for hiding this comment

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

If @casperklein later chimes in with input to approach this differently, I'll handle those changes for you.


Please make the following changes.

NOTE: You do not need to clean-up the commit history, keeping the existing commit history is fine as we apply a squash merge commit on approval. Slight benefit if we need to revert to prior revision of your contribution 👍

  • Update target/postfix/main.cf to include smtpd_discard_ehlo_keywords = silent-discard, dsn.

    • It will be the new default and enforced.
    • git blame should be sufficient for now to reference this PR for more information on the setting/decision if anyone needs to (future maintainers / contributors).
  • Update target/postfix/master.cf to include -o smtpd_discard_ehlo_keywords= for both submission(s) services.

  • Update the tests based on review feedback to simplify them:

    • user1 account instead of creating added + remove change detection usage.
    • No POSTFIX_DSN ENV necessary.
    • While only the 2nd test case is needed, I'd like to keep the 1st and 3rd for robustness / reference.
  • Revert changes to:

    • Dockerfile
    • mailserver.env
    • postfix.sh + variables-stack.sh
    • Delete esmtp_access
  • dsn-authenticated.txt - Replace the AUTH PLAIN line with the AUTH LOGIN lines for user1 account. Swap the added user in MAIL FROM and From lines to user1, it's still valid to login as user1 and have their address as the sender and recipient.

  • Document your change in CHANGELOG.md under the "Unreleased => Breaking" section with:

    - Postfix now defaults to supporting DSNs (_[Delivery Status Notifications](https://github.com/docker-mailserver/docker-mailserver/pull/3572#issuecomment-1751880574)_) only for authenticated users. This is a security measure to reduce spammer abuse of your DMS instance as a backscatter source.
      - If you need to modify this change, please let us know by opening an issue / discussion.
      - You can [opt-out (_enable DSNs_) via the `postfix-main.cf` override support](https://docker-mailserver.github.io/docker-mailserver/v12.1/config/advanced/override-defaults/postfix/) using the contents: `smtpd_discard_ehlo_keywords =`.
      - Likewise for authenticated users, the submission(s) ports (465 + 587) are configured internally via `master.cf` to keep DSNs enabled (_since authentication protects from abuse_). 
         
        If necessary, DSNs for authenticated users can be disabled via the `postfix-master.cf` override with the following contents:
         
        ```
        submission/inet/smtpd_discard_ehlo_keywords = silent-discard, dsn
        submissions/inet/smtpd_discard_ehlo_keywords = silent-discard, dsn
        ```

    Rendered preview:

    • Postfix now defaults to supporting DSNs (Delivery Status Notifications) only for authenticated users. This is a security measure to reduce spammer abuse of your DMS instance as a backscatter source.
      • If you need to modify this change, please let us know by opening an issue / discussion.

      • You can opt-out (enable DSNs) via the postfix-main.cf override support using the contents: smtpd_discard_ehlo_keywords =.

      • Likewise for authenticated users, the submission(s) ports (465 + 587) are configured internally via master.cf to keep DSNs enabled (since authentication protects from abuse).

        If necessary, DSNs for authenticated users can be disabled via the postfix-master.cf override with the following contents:

        submission/inet/smtpd_discard_ehlo_keywords = silent-discard, dsn
        submissions/inet/smtpd_discard_ehlo_keywords = silent-discard, dsn
        

Prior feedback relevance (obsoleted by above checklist)

Feedback to apply:

Feedback to ignore:

@allddd
Copy link
Contributor Author

allddd commented Oct 16, 2023

Very nice PR! Just a few touchups here and there. I mostly agree with @polarathene on the changes and added some feedback.

I highly appreciate the effort, and this is something we definitely need to take care of (since it may impact security).

I have only limited time to spare on this; I hope you excuse my superficial review. I trust @polarathene 100% with this PR though, so you needn't wait for my review to merge this PR after feedback has been applied.

Thanks for the review! No worries, we are all busy.

Please make the following changes.
...

Thank you for the detailed explanation. I actually like this approach better, but initially avoided making it the default because it might break some configurations.

Document your change in CHANGELOG.md under the "Unreleased => Breaking" section with:
...

The only thing I had to do differently here was that the entries in postfix-master.cf had to be without spaces.

submission/inet/smtpd_discard_ehlo_keywords = silent-discard, dsn
submission/inet/smtpd_discard_ehlo_keywords=silent-discard,dsn

After changing this, the tests worked again.

@polarathene
Copy link
Member

The only thing I had to do differently here was that the entries in postfix-master.cf had to be without spaces.

Good that we decided to test the other cases then 😁

That wasn't something I thought would be an issue though, I'll have to look at our script for it or update our related docs to address that gotcha.


I'll return to this PR later today, my system is acting up and needs my attention to resolve (WSL2 just ate a bunch of disk to the point I'm out of disk space + RAM and is unresponsive to shutdown, I can't seem to terminate the related process eating 10GB of memory).

@polarathene
Copy link
Member

Apologies for the delay!

The only thing I had to do differently here was that the entries in postfix-master.cf had to be without spaces.

Attempting to apply the setting with spaces (and double quote wrapped) via postconf -P fails with:

postconf: fatal: -Pe does not accept whitespace in parameter value

So doesn't seem like we can do anything about that 😅


Looks like all the feedback was addressed, so LGTM 👍

Thank you for the excellent contribution to DMS! 😎

Copy link
Member

@polarathene polarathene left a comment

Choose a reason for hiding this comment

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

I'll apply these, just some quick context for maintenance 👍

test/tests/parallel/set3/mta/dsn.bats Outdated Show resolved Hide resolved
test/tests/parallel/set3/mta/dsn.bats Outdated Show resolved Hide resolved
test/tests/parallel/set3/mta/dsn.bats Show resolved Hide resolved
@polarathene polarathene changed the title add POSTFIX_DSN= / configure how Postfix handles Delivery Status Notification (DSN) feat: Postfix permit DSN (Delivery Status Notification) only on authenticated ports (465 + 587) Oct 20, 2023
@polarathene polarathene added the kind/improvement Improve an existing feature, configuration file or the documentation label Oct 20, 2023
polarathene
polarathene previously approved these changes Oct 20, 2023
@polarathene
Copy link
Member

polarathene commented Oct 20, 2023

Test cases 2 and 3 are failing when first sending the unauthenticated mail (_send_email 'email-templates/dsn-unauthenticated').

I lack time to investigate right now, but it failing at this assertion in the helper:

_run_in_container_bash "nc ${NC_PARAMETERS} < /tmp/docker-mailserver-test/${TEMPLATE_FILE}.txt"
assert_success

The first test case passes, despite calling this method as well to send the unauthenticated template.


Test failure:

ok 27 [DSN] should always send a DSN when requested in 5774ms
not ok 28 [DSN] should only send a DSN when requested from ports 465/587 in 4079ms
# (from function `assert_success' in file test/test_helper/bats-assert/src/assert_success.bash, line 42,
#  from function `_send_email' in file test/helper/sending.bash, line 33,
#  in test file test/tests/parallel/set3/mta/dsn.bats, line 47)
#   `_send_email 'email-templates/dsn-unauthenticated'' failed
# [   INF   ]  mail.example.test is up and running
#
# -- command failed --
# status : 1
# output :
# --
#
# dms-test_dsn
not ok 29 [DSN] should never send a DSN in 4101ms
# (from function `assert_success' in file test/test_helper/bats-assert/src/assert_success.bash, line 42,
#  from function `_send_email' in file test/helper/sending.bash, line 33,
#  in test file test/tests/parallel/set3/mta/dsn.bats, line 79)
#   `_send_email 'email-templates/dsn-unauthenticated'' failed
# [   INF   ]  mail.example.test is up and running
#
# -- command failed --
# status : 1
# output :
# --

load "${REPOSITORY_ROOT}/test/helper/common"

BATS_TEST_NAME_PREFIX='[DSN] '
CONTAINER_NAME='dms-test_dsn'
Copy link
Member

Choose a reason for hiding this comment

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

At a glance, I think the issue could be from here.

  • The test goes straight into test cases, no setup_file().
  • The teardown() default should handle this inbetween without issue though, so a shared CONTAINER_NAME shouldn't be an issue due to sequential test run 🤷‍♂️ (parallel is only relevant to separate test files concurrently, not their individual test cases within)
  • But given that the 2nd and 3rd test cases are the ones that fail, it does seem like the containers may have failed to start correctly, thus the attempt to send mail to port 25 fails.

@allddd
Copy link
Contributor Author

allddd commented Oct 20, 2023

I have to say this is very strange, the failures seem to be completely random.
I ran all the tests twice before pushing without any problems.
Now I have tried again and it has failed, but then it succeeds two times after that.

This was not the case with the old configuration (using /etc/postfix/esmtp_access), so I tried changing it back to that and it just works, which makes it even stranger.
It would be good if someone more familiar with the test suite could look into this, I'm not sure exactly what the problem is.

@polarathene
Copy link
Member

polarathene commented Oct 20, 2023

I have to say this is very strange, the failures seem to be completely random.
I ran all the tests twice before pushing without any problems.
Now I have tried again and it has failed, but then it succeeds two times after that.

That's interesting. I remember a recent PR a test case was revised for an error log check that was also proving to be spotty in behaviour unrelated to the PR:

I don't seem to have mentioned it explicitly there, but I think it was related to this report for sieve errors. Basically there is a non-deterministic behaviour with file creation during startup, and if that creates two related files with a timestamp at the exact same time, instead of one expecting to be slightly newer, then it gets caught by the error log check added in that other test.

Doesn't seem to trip up our CI so far though AFAIK. This might be related, hard to say.

Related, checking successful mail delivery: #3554


@georglauterbach you've worked on this helper IIRC, any advice? I assume we could maybe assert_output partially on something prior to the assert_success as that would give a bit more context to the failure when it doesn't match successful delivery expectations?

@allddd for the time being I think since this is the only test triggering the failure for that helper, we'll need to block merging the PR. It's not unusual for tests to be flimsy for some reason, but since it's for a common helper method used elsewhere something isn't right 😅


If I find time I'll look into it.

My process is pretty simple, I just add a sleep 600 prior to the failing part of the test, then docker exec -it test_name_here bash and then I can run the command (or do that instead of bash). A little annoying when the test fails inconsistently though.

Success or failure in this case should be fine as we should be able to use the output to assert_output / refute_output like other tests do with partial matching on that. When the assert_output / refute_output fails, it should log that failing output. Mostly curious what the delivery failure output is caused by, so we can address that.

Copy link
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.

Overall LGTM 👍🏼 Nice PR!

I have added review feedback that you can apply, but the test needs a bit more work. I know, annoying. Please have a look at this test for Rspamd that I wrote. Moreover, the Postscreen test should provide you with a structure of how a test with multiple containers should look like.

I advocate for using setup_file here, using export CONTAINER_NAME and then setting it on-demand. This provides a unified place for starting containers. Moreover, we need to pay attention to using _wait_for_service postfix and _wait_for_smtp_port_in_container which could be important for this test.

With my proposals when using export MAIL_IDX=$(_send_email_and_get_id ...) you'd also gain the advantage of better checks against logs for a specific email.


If you have questions about this, just ping me :)


_init_with_defaults
# Unset `smtpd_discard_ehlo_keywords` to allow DSNs by default on any `smtpd` service:
mv "${TEST_TMP_CONFIG}/dsn/postfix-main.cf" "${TEST_TMP_CONFIG}/postfix-main.cf"
Copy link
Member

Choose a reason for hiding this comment

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

Why is mv and not cp being used here?

Suggested change
mv "${TEST_TMP_CONFIG}/dsn/postfix-main.cf" "${TEST_TMP_CONFIG}/postfix-main.cf"
cp "${TEST_TMP_CONFIG}/dsn/postfix-main.cf" "${TEST_TMP_CONFIG}/postfix-main.cf"

Copy link
Member

Choose a reason for hiding this comment

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

Normally we use mv as _init_with_defaults would copy the config dir into a temporary location for the container being setup (directory with the container name).

Since that is meant to be isolated, the pattern here is just moving from the dsn directory to the root test dir, as this whole directory is mounted into /tmp/docker-mailserver.

Not the greatest solution, but that's how it's been for quite some time. I'm not too bothered as it works, and the eventual plan is to switch to compose.yaml with :ro mounts where possible.


mv or cp, doesn't matter much either way 🤷‍♂️ (mv just communicates the above a bit better)

test/tests/parallel/set3/mta/dsn.bats Outdated Show resolved Hide resolved
test/tests/parallel/set3/mta/dsn.bats Outdated Show resolved Hide resolved
test/tests/parallel/set3/mta/dsn.bats Show resolved Hide resolved
test/tests/parallel/set3/mta/dsn.bats Show resolved Hide resolved
test/tests/parallel/set3/mta/dsn.bats Outdated Show resolved Hide resolved
test/tests/parallel/set3/mta/dsn.bats Outdated Show resolved Hide resolved
test/tests/parallel/set3/mta/dsn.bats Outdated Show resolved Hide resolved
@allddd
Copy link
Contributor Author

allddd commented Oct 21, 2023

Thanks for the feedback @georglauterbach, it helped me get it stable again. :)
Now I was able to run the tests several times without any errors.
I will address all comments here as it is easier for me to do so:


I advocate for using setup_file here, using export CONTAINER_NAME and then setting it on-demand.

It is indeed nicer this way, especially with multiple containers.


Why is mv and not cp being used here?

No particular reason, it was used in the example @polarathene sent, so I just copied it.


Following our naming convention, this should be CUSTOM_SETUP_ARGUMENTS

I've tried to make it look as similar as possible. As for why I used it, I think it was because some of the first tests I looked at also use it.

grep -rl 'CONTAINER_ARGS_ENV_CUSTOM' docker-mailserver/

docker-mailserver/test/tests/parallel/set1/dovecot/dovecot_sieve.bats
docker-mailserver/test/tests/parallel/set3/mta/lmtp_ip.bats
docker-mailserver/test/tests/parallel/set3/mta/smtp_delivery.bats
docker-mailserver/test/tests/parallel/set3/container_configuration/process_check_restart.bats
docker-mailserver/test/tests/parallel/set3/scripts/setup_cli.bats
docker-mailserver/test/tests/serial/tests.bats

I'd add _wait_for_service postfix & _wait_for_smtp_port_in_container

I think that this actually solved the problem, thank you very much.


With my proposals when using export MAIL_IDX=$(_send_email_and_get_id ...) you'd also gain the advantage of better checks against logs for a specific email.

I thought this would be a great option as it would allow me to grep more accurately, but unfortunately it does not work in this case.

_run_in_container grep "${MAIL_ID}: ${LOG_DSN}" /var/log/mail/mail.log

As we currently send email using nc, this is not really possible as no email is sent at all, so there is no ID to get.
Here is the log output:

Oct 21 19:47:55 mail postfix/smtpd[704]: connect from localhost[127.0.0.1]
Oct 21 19:47:55 mail opendmarc[542]: ignoring connection from localhost
Oct 21 19:47:55 mail postfix/smtpd[704]: improper command pipelining after HELO from localhost[127.0.0.1]: MAIL FROM: user@external.tld\nRCPT TO: user1@localhost.localdomain NOTIFY=success,failure\nDATA\nFrom:
Oct 21 19:47:55 mail postfix/smtpd[704]: warning: non-SMTP command from localhost[127.0.0.1]: From: Docker Mail Server <dockermailserver@external.tld>
Oct 21 19:47:55 mail postfix/smtpd[704]: disconnect from localhost[127.0.0.1] helo=1 mail=1 rcpt=0/1 data=0/1 unknown=0/1 commands=2/5

Even if this was not the case, I'm not sure how accurate the ID extraction would be, as I send multiple emails and DSNs in the same container.

# This functions assumes **no concurrent sending of emails to the same container**!
# If two clients send simultaneously, there is no guarantee the correct ID is
# chosen. Sending more than one mail at any given point in time with this function
# is UNDEFINED BEHAVIOR!

@polarathene
Copy link
Member

Following our naming convention, this should be CUSTOM_SETUP_ARGUMENTS

I've tried to make it look as similar as possible. As for why I used it, I think it was because some of the first tests I looked at also used it.

Good spotting, that'd be from an earlier iteration when this approach was only focused on ENV adjustment, but now just appends args to the docker create command.

I'd add _wait_for_service postfix & _wait_for_smtp_port_in_container

I think that this actually solved the problem, thank you very much.

Thanks @georglauterbach 🙏

I've not been working on tests for a while that I thought this was implicit, but we don't always need it to minimize container startup time, so thanks for catching that 👍

Copy link
Member

@polarathene polarathene left a comment

Choose a reason for hiding this comment

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

Glad the testing issue was resolved, LGTM! 👍

test/tests/parallel/set3/mta/dsn.bats Show resolved Hide resolved
Copy link
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 👍🏼

@georglauterbach georglauterbach merged commit eacc379 into docker-mailserver:master Oct 22, 2023
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants