[GH-ISSUE #8] More flexible control over allowed user "from" address #1

Closed
opened 2026-02-26 18:32:55 +03:00 by kerem · 4 comments
Owner

Originally created by @JonathonReinhart on GitHub (Feb 13, 2021).
Original GitHub issue: https://github.com/decke/smtprelay/issues/8

Prior to #7, authorized users could only send from a single email address. #7 allowed that field in the allowedUsers file to be empty, allowing that user to send from any email address.

I would like to have more control, and allow something between 1 and ∞ addreses.

One use case I've identified is very common on Linux machines, running Postfix, where sendmail (without -r or any remapping) will send from $USER@appserver.internal.example.com. That same machine might also run an application that wants to send as app@example.com This won't work with smptrelay today, without allowing the server to send as (anyone)@example.com which is more dangerous.

Options

I have a couple different ideas for handling this:

Option 1

Expand the allowedUsers parts[2] syntax even further with two enhancements:

  • Allow internal.example.com (or perhaps @internal.example.com) to mean (anyone)@internal.example.com
  • Allow a comma-separated list of allowed email addresses

The config file for my stated usecase would be:

appserver  bcrypt-password-hash app@example.com,appserver.internal.example.com

Pros:

  • Simple, readable

Cons:

  • Not completely flexible

Option 2

Update the allowedUsers parts[2] syntax to accept a regular expression.

The config file for my stated usecase would be:

appserver passwdhash  ^(app@example\.com|.*@appserver\.internal\.example\.com)$

I'm not sure that this can be implemented without breaking backwards compatibility. For example, consider an old config file like this:

joe passwdhash joe@example.com

If we switched parts[2] to unconditionally be a regex, then the pattern joe@example.com would erroneously also match:

  • bobjoe@example.com
  • joe@example.com.edu

There are options here:

  • Break compatibility, release a v2.0 with a warning
  • Require a prefix to use regex, e.g. regex::
    joe passwdhash regex:^.*@example.com$
  • Require a config file option that enables regex (e.g. allowed_users_uses_regex = true)
  • Try to auto-detect the use of regex (bad idea; very ambiguous)

Pros:

  • Very flexible
  • Consistent with other config options that allow regex (allowedRecipients, allowedSender)

Cons:

  • Less readable for most use cases
  • Hard to implement without breaking backwards compatibility

I suggest Option 1. A regex is probably more powerful than any user will need, and there are a lot of characters allowed in the local-part of an email address that are special in a regex, requiring escaping.

Originally created by @JonathonReinhart on GitHub (Feb 13, 2021). Original GitHub issue: https://github.com/decke/smtprelay/issues/8 Prior to #7, authorized users could only send from a single email address. #7 allowed that field in the `allowedUsers` file to be empty, allowing that user to send from *any* email address. I would like to have more control, and allow something between 1 and ∞ addreses. One use case I've identified is very common on Linux machines, running Postfix, where `sendmail` (without `-r` or any remapping) will send from `$USER@appserver.internal.example.com`. That same machine might also run an application that wants to send as `app@example.com` This won't work with `smptrelay` today, without allowing the server to send as `(anyone)@example.com` which is more dangerous. # Options I have a couple different ideas for handling this: ## Option 1 Expand the `allowedUsers` `parts[2]` syntax even further with two enhancements: - Allow `internal.example.com` (or perhaps `@internal.example.com`) to mean `(anyone)@internal.example.com` - Allow a comma-separated list of allowed email addresses The config file for my stated usecase would be: ``` appserver bcrypt-password-hash app@example.com,appserver.internal.example.com ``` Pros: - Simple, readable Cons: - Not completely flexible ## Option 2 Update the `allowedUsers` `parts[2]` syntax to accept a regular expression. The config file for my stated usecase would be: ``` appserver passwdhash ^(app@example\.com|.*@appserver\.internal\.example\.com)$ ``` I'm not sure that this can be implemented without breaking backwards compatibility. For example, consider an old config file like this: ``` joe passwdhash joe@example.com ``` If we switched `parts[2]` to unconditionally be a regex, then the *pattern* `joe@example.com` would erroneously also match: - `bobjoe@example.com` - `joe@example.com.edu` There are options here: - Break compatibility, release a v2.0 with a warning - Require a prefix to use regex, e.g. `regex:`: `joe passwdhash regex:^.*@example.com$` - Require a config file option that enables regex (e.g. `allowed_users_uses_regex = true`) - Try to auto-detect the use of regex (bad idea; very ambiguous) Pros: - Very flexible - Consistent with other config options that allow regex (`allowedRecipients`, `allowedSender`) Cons: - Less readable for most use cases - Hard to implement without breaking backwards compatibility --- I suggest Option 1. A regex is probably more powerful than any user will need, and there are a lot of characters allowed in the [local-part](https://en.wikipedia.org/wiki/Email_address#Local-part) of an email address that are special in a regex, requiring escaping.
kerem closed this issue 2026-02-26 18:32:55 +03:00
Author
Owner

@decke commented on GitHub (Feb 13, 2021):

Is there a reason why you cannot have two different users?

<!-- gh-comment-id:778573120 --> @decke commented on GitHub (Feb 13, 2021): Is there a reason why you cannot have two different users?
Author
Owner

@JonathonReinhart commented on GitHub (Feb 13, 2021):

Is there a reason why you cannot have two different users?

The way I'm using smtprelay, each internal server machine has its local MTA (Postfix or Exim4) configured to use the relay, and is configured with a username. This MTA handles mail from either local sendmail invocations (which will usually send as e.g. root@server.internal.example.com) or "applications" (which may send as e.g. app@example.com). By allowing this one authenticated user to send from several addresses, or from an entire subdomain, it greatly simplifies per-server configuration.

<!-- gh-comment-id:778643774 --> @JonathonReinhart commented on GitHub (Feb 13, 2021): > Is there a reason why you cannot have two different users? The way I'm using `smtprelay`, each internal server machine has its local MTA (Postfix or Exim4) configured to use the relay, and is configured with a username. This MTA handles mail from either local `sendmail` invocations (which will usually send as e.g. `root@server.internal.example.com`) or "applications" (which may send as e.g. `app@example.com`). By allowing this one authenticated user to send from several addresses, or from an entire subdomain, it greatly simplifies per-server configuration.
Author
Owner

@decke commented on GitHub (Feb 14, 2021):

Okay, this case is a bit similar to "account with multiple sender addresses" and I see that it makes sense. What I am not convinced yet is how to properly integrate it. The way you have chosen seems problematic because it makes assumptions what it means that is written in the email field. A kind of regex, glob, pattern would avoid this problem but I agree that it can be a pain to read and parse properly with our weak format in that file.

<!-- gh-comment-id:778828176 --> @decke commented on GitHub (Feb 14, 2021): Okay, this case is a bit similar to "account with multiple sender addresses" and I see that it makes sense. What I am not convinced yet is how to properly integrate it. The way you have chosen seems problematic because it makes assumptions what it means that is written in the email field. A kind of regex, glob, pattern would avoid this problem but I agree that it can be a pain to read and parse properly with our weak format in that file.
Author
Owner

@JonathonReinhart commented on GitHub (Feb 14, 2021):

The way you have chosen seems problematic because it makes assumptions what it means that is written in the email field.

Did you see PR #9 yet? I implemented Option 1, which unambiguously expands the meaning of the third field without breaking backwards compatibility. It is running in production right now.

In #9, the field is a comma-separated list of email addresses or domains. That remains backwards-compatible with the existing single address: An existing single address will be interpreted as a list of of length 1. I have unit tests to prove this is backwards-compatible.

Edit: Err, sorry I didn't see your comments on #9. I see now that I didn't realize that smtprelay could receive mail with local-only addresses (no @domain.com).

<!-- gh-comment-id:778833709 --> @JonathonReinhart commented on GitHub (Feb 14, 2021): > The way you have chosen seems problematic because it makes assumptions what it means that is written in the email field. Did you see PR #9 yet? I implemented Option 1, which unambiguously expands the meaning of the third field *without* breaking backwards compatibility. It is running in production right now. In #9, the field is a comma-separated list of email addresses or domains. That remains backwards-compatible with the existing single address: An existing single address will be interpreted as a list of of length 1. I have unit tests to prove this is backwards-compatible. *Edit:* Err, sorry I didn't see your comments on #9. I [see now](https://github.com/decke/smtprelay/pull/9#issuecomment-778836237) that I didn't realize that smtprelay could receive mail with local-only addresses (no `@domain.com`).
Sign in to join this conversation.
No labels
bug
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/smtprelay#1
No description provided.