Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

feat: SPOOF_PROTECTION=1 support config to relax sender restrictions by login#4044

Draft
ncovercash wants to merge 8 commits intodocker-mailserver:masterdocker-mailserver/docker-mailserver:masterfrom
ncovercash:add-send-only-aliasesncovercash/docker-mailserver:add-send-only-aliasesCopy head branch name to clipboard
Draft

feat: SPOOF_PROTECTION=1 support config to relax sender restrictions by login#4044
ncovercash wants to merge 8 commits intodocker-mailserver:masterdocker-mailserver/docker-mailserver:masterfrom
ncovercash:add-send-only-aliasesncovercash/docker-mailserver:add-send-only-aliasesCopy head branch name to clipboard

Conversation

@ncovercash
Copy link
Copy Markdown

@ncovercash ncovercash commented Jun 2, 2024

Description

Currently, the only way to allow a user to send mail as another user (for example, to allow admin@example.com to send as user@example.com) would be to:

  • disable SPOOF_PROTECTION (undesirable as it would allow any user to spoof any other user)
  • alias user@example.com to admin@example.com (undesirable as user@example.com's mail would be sent to the admin mailbox)
  • manually edit configurations/map files into the container (not very user-friendly)

To improve this experience, this PR adds a new configuration file, postfix-regexp-send-only.cf, which allows configuring send-only aliases. These aliases differ from regular aliases in that they do not affect incoming mail, only outgoing, enabling admin/system accounts to send as other users, and with all the granular access control which regex can offer.

Some use cases could include:

  • Allowing an administrator to send as other user accounts, particularly to aid debugging of mail delivery issues for a certain user/domain
  • Permitting system/service accounts to send as a user
  • ...probably some more that I cannot think of off the top of my head.

Fixes #4042, relates to #2819

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 (also included here)

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my 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
  • I have added information about changes made in this PR to CHANGELOG.md

Questions

  • Which set inside test/tests/parallel should my tests go in? I did not see any that related to postfix/auth, so I created a folder inside set2 as it seemed to be the smallest test set; please let me know how this should be organized to best fit in with the rest of the tests.
    • As part of these changes, I was able to consolidate the current spoofing tests from the main tests.bats into this separate parallel file, since they cover the same cases.

@ncovercash ncovercash marked this pull request as ready for review June 2, 2024 20:22
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2024

Documentation preview for this PR is ready! 🎉

Built with commit: 99514c1

@polarathene
Copy link
Copy Markdown
Member

  • alias user@example.com to admin@example.com (undesirable as user@example.com's mail would be sent to the admin mailbox)

We forbid aliasing an actual account. So that is presently not possible. Sharing an alias to multiple recipients is though (not officially endorsed/supported by DMS however).

  • manually edit configurations/map files into the container (not very user-friendly)

Isn't that the same as what this PR proposes by introducing a new regexp config to manage which sender addresses a user login (DMS account / address) can use?

Or you are referring to only the additional integration in main.cf? Which could be handled via user-patches.sh:

#!/bin/bash

# Include `regexp-send-only` to relax `SPOOF_PROTECTION=1` sender address restrictions for specific logins:
cp -f /tmp/docker-mailserver/postfix-regexp-send-only.cf /etc/postfix/regexp-send-only
postconf 'smtpd_sender_login_maps = unionmap:{ texthash:/etc/postfix/virtual, hash:/etc/aliases, pcre:/etc/postfix/maps/sender_login_maps.pcre, pcre:/etc/postfix/regexp-send-only }'

Initial Review / Concerns

I'm a little confused, while there is value in this PR, are you not already repeating the functionality I made you aware of in #4042 (comment) ? (EDIT: PR adds separate config for send-only support)

  • sender_login_maps.pcre is effectively the SPOOF_PROTECTION=1 feature (by using a regex lookup that restricts sender address to that of the DMS account).
  • Prepending regex patterns above that line would give you similar functionality?
  • This is not only for aliases, but any address you allow will be permitted as a sender address, including ones DMS has no authority over (support@github.com).
  • A separate regexp config postfix-regexp.cf has been used / advised in the past (with the caveat that it is shared with virtual aliases lookup), it is also used in our test-suite for SPOOF_PROTECTION=1:

    image

  • Using a separate regex table should be ok, but it was noted that avoiding regex was the preferred choice to support (you made this same mistake in your config example):

    image

  • It may be appropriate to continue using the existing postfix-regexp.cf file for this, and drop the support for virtual aliases with it, as the actual need for users to have regexp virtual aliases may be low? It was only added AFAIK to workaround SPOOF_PROTECTION=1 issue before that was fixed via using unionmap instead? (although I am not opposed to keeping regex support for both via separate files):

    image

Copy link
Copy Markdown
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 need to push out a rewrite docs that affects user-management.md. Your change will need to be adjusted to that afterwards. I'll try get that done for you by this weekend.
  • Likewise the CHANGELOG.md items will need to be rebased after the v14 release. This is too late to land in that and will have to be delayed to 14.1.
  • I've not reviewed the test contribution yet, I have seen your questions but will address that closer to resolving this PR as I'm a bit short on time and this is touching an area of functionality that has known issues already.
  • unionmap logic in spoofing.sh won't be accepted. I think my existing PR has concerns related to this area with LDAP, so that may need to be addressed prior. All you're really doing here is appending a string of additional files, which could be handled via variable.

A good contribution overall, I was only expecting docs so I apologize about any blockers I'm responsible for. I'll see what I can do to get those out of the way.

Comment thread docs/content/config/user-management.md Outdated
Comment on lines +91 to +96
```cf
/^.*@example.com$/ admin@example.com
/^.*$/ superadmin@example.com
```

In this example, `admin@example.com` would be able to send as any address at `example.com` and `superadmin@example.com` would be able to send as any address at any domain.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

superadmin@example.com will not be able to send as user@example.com AFAIK, this is a caveat with regex lookup tables that you need to be aware of. The 1st match from top-down on the sender address will then check to the right-side value(s) for permitted logins (which are often email addresses in DMS, but they could just be user names).

You did not escape . for .com in the regex, in this example it shouldn't be a real issue, since alternative characters aren't going to produce a valid sender address, but it's still a caveat to be careful of:

jan.doe@example.com would also grant janedoe@example.com sender address to the login account, which might be a security problem when using the feature for accounts that aren't admins.

Copy link
Copy Markdown
Author

@ncovercash ncovercash Jun 3, 2024

Choose a reason for hiding this comment

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

Good catch on both counts; I'll clarify that in the documentation and warn about the caveats.

It looks like the following would allow superadmin@example.com to get the desired effect:

Suggested change
```cf
/^.*@example.com$/ admin@example.com
/^.*$/ superadmin@example.com
```
In this example, `admin@example.com` would be able to send as any address at `example.com` and `superadmin@example.com` would be able to send as any address at any domain.
```cf
/^.*@example.com$/ admin@example.com superadmin@example.com
/^.*$/ superadmin@example.com
```
In this example, `admin@example.com` would be able to send as any address at `example.com` and `superadmin@example.com` would be able to send as any address at any domain.
...some notes about needing to order/etc

}

function _handle_postfix_regexp_send_only_config() {
: >/etc/postfix/regexp-send-only
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd prefer not creating a file explicitly when it's not used.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I was just copying the regular postfix-regexp logic here — would I be OK to also remove the same thing in the _handle_postfix_regexp_config() above (and corresponding # TODO: Investigate why this file is always created, nothing seems to append only the cp below? comment)?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There's probably a related issue already open about details for that.

Without looking for that, I can't quite say. I've not had as much time for DMS as I'd like, but if the change was delayed I may have detailed why. I'd leave it alone for now, unless you have time to sink 😅

Proper actionable feedback from me is going to need to wait until I have the time to refresh on related context like this. I'll try to get that sorted for you by this weekend if possible, sorry about the friction that adds.

Comment on lines +17 to +21
if [[ -f /etc/postfix/regexp && -f /etc/postfix/regexp-send-only ]]; then
postconf 'smtpd_sender_login_maps = unionmap:{ texthash:/etc/postfix/virtual, hash:/etc/aliases, pcre:/etc/postfix/maps/sender_login_maps.pcre, pcre:/etc/postfix/regexp, pcre:/etc/postfix/regexp-send-only }'
elif [[ -f /etc/postfix/regexp-send-only ]]; then
postconf 'smtpd_sender_login_maps = unionmap:{ texthash:/etc/postfix/virtual, hash:/etc/aliases, pcre:/etc/postfix/maps/sender_login_maps.pcre, pcre:/etc/postfix/regexp-send-only }'
elif [[ -f /etc/postfix/regexp ]]; then
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not acceptable. See the related SPOOF_PROTECTION=1 issue.

This section needs to be refactored to unify with LDAP. You'll need to wait on that being resolved. I am adding friction here due to blockers I introduce external to this PR, I'll need to address those first.

@polarathene polarathene added this to the v14.1.0 milestone Jun 3, 2024
@ncovercash
Copy link
Copy Markdown
Author

Isn't that the same as what this PR proposes by introducing a new regexp config to manage which sender addresses a user login (DMS account / address) can use?

Yes; the primary purpose of this was to have a more "DMS-friendly" way that would 1) be supported in the documentation and 2) not require the user directly patching the main.cf. Sure, this could all be accomplished by a user adding their patches, but theoretically so is most of the config, so it seems like it'd be good for DMS to support/expose what it can?

Prepending regex patterns above that line would give you similar functionality?

Sure; I can edit the commands to prepend the user-provided configuration above this and use the same file; I personally felt it was a little cleaner to have separate files for this and the user-provided ones. Your judgement there, just let me know what would be best.

This is not only for aliases, but any address you allow will be permitted as a sender address

Yes; I can rewrite the added documentation if there's a better way to describe it (maybe "permitted sender addresses"?). Let me know if there's a name you would prefer.

A separate regexp config postfix-regexp.cf has been used / advised in the past (with the caveat that it is shared with virtual aliases lookup), it is also used in our test-suite for SPOOF_PROTECTION=1

This feature does not overlap, since postfix-regexp.cf will also redirect incoming mail. This specifically is for outgoing mail only. And yes, I saw the test — I moved it over into my test suite.

Using a separate regex table should be ok, but it was noted that avoiding regex was the preferred choice to support (you made this same mistake in your config example)

Good catch; I can change to a non-regex version, I just wanted to align closely with the existing postfix-regexp.cf

It may be appropriate to continue using the existing postfix-regexp.cf file for this, and drop the support for virtual aliases with it

I personally use postfix-regexp.cf for the virtual alias support ☹️. I use this to redirect postmaster, webmaster, and hostmaster to one centralized inbox (woo, wearing many hats), as well as a few other things, so it'd be an unfortunate feature to lose.

@polarathene polarathene changed the title Add send-only aliases feat: SPOOF_PROTECTION=1 support config to relax sender restrictions by login Jun 3, 2024
@ncovercash
Copy link
Copy Markdown
Author

A good contribution overall, I was only expecting docs so I apologize about any blockers I'm responsible for. I'll see what I can do to get those out of the way.

I'm happy to hold off, I did not realize there were blockers. I have this temporarily worked around on my local mailserver, but I wanted to make a better experience for those who came after me. And no worries, I thought this would be a doc-only thing and then I realized it was (relatively) easy to add first-class support and figured may as well.

No rush at all, let me know when I need to update my changes to align with yours. Thanks for the review!

@polarathene
Copy link
Copy Markdown
Member

I personally felt it was a little cleaner to have separate files for this and the user-provided ones. Your judgement there, just let me know what would be best.

AFAIK unionmap will query all config files for the sender address, and return any results of valid logins that can use it.

It's probably best that we keep sender_login_maps.pcre as-is and don't modify it then. It can remain as an internal config as you suggest, using separate user config.


Good catch; I can change to a non-regex version, I just wanted to align closely with the existing postfix-regexp.cf

I think it would be simpler to document and support a non-regex table. If some users request regex support, then we could add that as another file.

It may be appropriate to continue using the existing postfix-regexp.cf file for this, and drop the support for virtual aliases with it

I personally use postfix-regexp.cf for the virtual alias support ☹️. I use this to redirect postmaster, webmaster, and hostmaster to one centralized inbox (woo, wearing many hats), as well as a few other things, so it'd be an unfortunate feature to lose.

👍 No worries, we can have both then :)


I'm happy to hold off, I did not realize there were blockers.
No rush at all, let me know when I need to update my changes to align with yours. Thanks for the review!

Thanks ❤️ I really want to resolve the LDAP PR and related docs rewrite this month.

The LDAP test also touches on SPOOF_PROTECTION=1 but there's a bug IIRC that was being resolved, which is probably why the test cases in tests.bats hadn't yet been migrated as you've tackled in this PR. I was probably meaning to handle that afterwards.

After that I can better go over the related SPOOF_PROTECTION=1 issue again, and help push this forward. If the LDAP PR does become an actual blocker this PR would be delayed until v15.

So uhh, if you're comfortable with it, perhaps best to just wait until later this month before taking any further action.

@ncovercash
Copy link
Copy Markdown
Author

Sure thing, no worries! @ me when you're ready to proceed!

@ncovercash ncovercash marked this pull request as draft June 3, 2024 02:30
@georglauterbach georglauterbach added meta/feature freeze On hold due to upcoming release process and removed meta/feature freeze On hold due to upcoming release process labels Jun 3, 2024
@github-actions github-actions Bot added the meta/stale This issue / PR has become stale and will be closed if there is no further activity label Jun 26, 2024
@docker-mailserver docker-mailserver deleted a comment from github-actions Bot Jun 26, 2024
@polarathene polarathene added stale-bot/ignore Indicates that this issue / PR shall not be closed by our stale-checking CI and removed meta/stale This issue / PR has become stale and will be closed if there is no further activity labels Jun 26, 2024
@eadoking
Copy link
Copy Markdown

eadoking commented Aug 1, 2024

Hi @ncovercash,

I just have some security concerns about the admin@example.com/ superadmin@example.com send email as user@example.com

  • what if for example it was a targeted attack by the admin? not for good purpose for testing email !!
  • will the send message appears on the sent folder on the user@example.com ?
  • can the admin/superadmin by any means delete the sent message from user@example.com ?
  • can the admin/superadmin by any means read the respond for the user@example.com ?

@polarathene
Copy link
Copy Markdown
Member

  • what if for example it was a targeted attack by the admin? not for good purpose for testing email !!

They're an admin, it would not be surprising for them to have elevated permissions to do things that could be abused. That concern is unrelated to this feature.


  • will the send message appears on the sent folder on the user@example.com?

No. Without SPOOF_PROTECTION=1, you can send mail as any sender address you like. You could even try ceo@github.com, it will be rejected if sent outbound to any actual MTA with standard security checks since you don't actually own github.com.

The PR here is just to allow relaxing what additional sender addresses can be used per user. A sent folder is something your mail client keeps on it's end AFAIK (unless your mailbox in /var/mail says otherwise?).


  • can the admin/superadmin by any means delete the sent message from user@example.com?

Not with this feature. If the admin has control of the DMS deployment they can do whatever they want with the container really.

AFAIK, your mail client submits mail to DMS when you want to send mail out, that will temporarily be stored in a mail queue, and then is sent outbound to an external mail server or delivered to a mailbox within DMS. So if the sent copy is only kept with your mail client storage (like Thunderbird), it can't be touched.

If it's in /var/mail, this feature won't enable deletion. This feature is for Postfix service, whereas mailbox storage is handled by the Dovecot service. A related feature is Dovecot Master Users, which allows an admin to login as any user without needing that users password. If that admin had access to the DMS container, they could also read the mail content directly at /var/mail without any user login needed.


  • can the admin/superadmin by any means read the respond for the user@example.com?

Technically yes. If your response is submitted to DMS, Postfix will receive it and it'll end up in the queue. It could be monitored and read there if that is the only time it is available in transit. That requires actual access to the DMS container, not just a DMS user account (Postfix/Dovecot login).

Otherwise same caveats regarding deleting a sent copy as for being able to read one.


There is an on-disk encryption feature for /var/mail content that I will eventually contribute that with support for per-user keys. Then none of the concerns above really apply for access to mail content. Unless they have the ability to read memory or something else to read unencrypted content arriving inbound (delivery) or your credentials after TLS is terminated... mail queue concern would still be valid AFAIK as it's only for encrypting mail stored to /var/mail.

You can have your mail client use PGP encryption so long as the recipient also has this configuration to decrypt the mail, and then the mail is always encrypted between systems, DMS won't know the contents or be able to access it then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/configuration (file) area/documentation area/features area/tests kind/improvement Improve an existing feature, configuration file or the documentation service/postfix stale-bot/ignore Indicates that this issue / PR shall not be closed by our stale-checking CI

Projects

Status: Implementation Phase

Development

Successfully merging this pull request may close these issues.

feature request: allow sender spoofing for certain accounts

4 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.