7

It would be nice to reject incoming emails which use one of my virtual domains as sender address while not being a legitimate user of mine.

I know that I can reject incoming emails which use an existing alias/account name using smtpd_sender_restrictions=reject_sender_login_mismatch, this does however still allow attackers to use a non-existant emailaddress with one of my virtual domains. (Which is favored in regards to spam detection).

What's the best way to reject incoming mails which use one of my virtual domains and aren't authenticated to do so?

SPF as well as DKIM are set up but configured to SoftFail, due to problems with mailinglists and forwards. I am not looking for SPF or DKIM but a solution for the postfix server that is the MX of the aforementioned domains.

Zulakis
  • 4,191
  • 14
  • 44
  • 75
  • Using `reject_sender_login_mismatch` and `reject_unlisted_sender`? – masegaloeh May 06 '15 at 08:20
  • Try using smtpd_sender_restrictions, first permit_mynetwork and permit_sasl_authenticated, then use a pcre:/etc/postfix/sender_access file where you can try /@my\.domain$/ REJECT – Dan May 06 '15 at 08:33
  • @Dan look at the second method I listed, it is very similar to what you suggested. – Zulakis May 06 '15 at 09:00
  • @masegaloeh Can you explain? man postconf wasn't really clear on what reject_unlisted_sender does, it seemed to me that it does reject ALL unknown senders? (http://www.postfix.org/postconf.5.html#reject_unlisted_sender) Maybe it's a better way to do it than what I did. – Zulakis May 06 '15 at 09:00
  • `reject_sender_login_mismatch` = reject client who not (SASL) logged in as that MAIL FROM address owner; `reject_unlisted_sender` = reject client who send email from unknown sender addresses – masegaloeh May 06 '15 at 09:20
  • @masegaloeh It rejects all unkown sender addresses? How would that help? – Zulakis May 06 '15 at 09:21
  • You said it in the post, "this does however still allow attackers to use a non-existant emailaddress with one of my virtual domains". I think we can solve it by using `reject_unlisted_sender` :D (non-tested idea BTW :p) – masegaloeh May 06 '15 at 09:22
  • @masegaloeh Yeah but then legitimate senders couldn't use their domains either, because they are not listed in my virtual domains/destinations? :D – Zulakis May 06 '15 at 09:23
  • 1
    **Nope**. postfix only reject if (1) sender domain in `virtual_mailbox_domains` and (2) sender address doesn't listed in `virtual_mailbox_maps` and so on. See http://www.postfix.org/postconf.5.html#smtpd_reject_unlisted_sender – masegaloeh May 06 '15 at 09:25
  • @masegaloeh Ahh, I see now. You are quite an postfix expert :-) Do you have any idea how much this check would cost (IO-wise) in comparison to the other two methods in my answer? – Zulakis May 06 '15 at 09:39
  • +1 for your solution. In IO-terms, there are no difference as you have virtual_mailbox_(domains|maps) in `mysql`. One of the advantage of my suggested solution is you don't have to generate another query, when your table structure was changed, or you don't use MySQL anymore. But still, (1) my idea is non-tested, and (2) my assumption about your mail setup could be wrong, so please do test carefully before deploying to production. – masegaloeh May 06 '15 at 09:49

4 Answers4

10

I found two possible methods, but maybe there is a better way.

1st method:

smtpd_sender_restrictions =
    reject_sender_login_mismatch,
    permit_sasl_authenticated,
    permit

Now I modified my smtpd_sender_login_maps to return an entry of admin if the domain exists in the domains table. This way a record is returned, even when the emailadress doesn't exist as maibox/alias, but not when a foreign domain is the from address.

table = domain
query = SELECT username AS allowedUser FROM mailbox WHERE username="%s" AND deleted_at IS NULL \
UNION SELECT goto FROM alias WHERE address="%s" AND active = 1 \
UNION select 'admin' from domain where domain = '%d'

2nd method:

This approach uses a check_sender_access lookup which returns a reject action if the domain is a virtual one and the user is not sasl_authenticated.

smtpd_sender_restrictions =
    reject_sender_login_mismatch,
    permit_sasl_authenticated,
    check_sender_access proxy:mysql:$config_directory/mysql_reject_virtual_domains.cf,
    permit

mysql_reject_virtual_domains.cf:

table = domain
query = select 'Reject 530 SMTP authentication is required' from domain where domain = '%d'

3rd method (thanks to masegaloeh):

smtpd_sender_restrictions =
    reject_sender_login_mismatch,
    permit_sasl_authenticated
    reject_unlisted_sender,
    permit

I don't know how many cpu-load/SQL-queries reject_unlisted_sender generates, as it checks quite many things:


Request that the Postfix SMTP server rejects mail from unknown sender addresses, even when no explicit reject_unlisted_sender access restriction is specified. This can slow down an explosion of forged mail from worms or viruses.

An address is always considered "known" when it matches a virtual(5) alias or a canonical(5) mapping.

  • The sender domain matches $mydestination, $inet_interfaces or $proxy_interfaces, but the sender is not listed in $local_recipient_maps, and $local_recipient_maps is not null.
  • The sender domain matches $virtual_alias_domains but the sender is not listed in $virtual_alias_maps.
  • The sender domain matches $virtual_mailbox_domains but the sender is not listed in $virtual_mailbox_maps, and $virtual_mailbox_maps is not null.
  • The sender domain matches $relay_domains but the sender is not listed in $relay_recipient_maps, and $relay_recipient_maps is not null.

Zulakis
  • 4,191
  • 14
  • 44
  • 75
1

The righteous way is to setup SPF for your domain and enable SPF in the MTA. Then you'll get protection not only for your own domain forging but also for all other domains having SPF enabled.

Kondybas
  • 6,864
  • 2
  • 19
  • 24
1

You should try to implement at least one of the followings (both is better):

alexus
  • 12,342
  • 27
  • 115
  • 173
  • 3
    Please have a look at my note regarding SPF/DKIM in the question. – Zulakis May 05 '15 at 15:03
  • `softfail` that's like it's not even enabled, you should look into enforcing it. – alexus May 05 '15 at 15:08
  • 2
    @alexus The SPF evaluation might still be relevant for spam detection *after* the message has been accepted, like spamassin does. The point is, that SPF should be enforced only for the own domain when the messages didn't arrive on the system an can be still rejected. – sebix May 05 '15 at 15:11
1

Yet another 1st method with separate query without unions:

virtual_sender_mailbox_maps.cf

query = SELECT '%s' AS email FROM domains WHERE name='%d' AND active=TRUE

main.cf

smtpd_sender_login_maps = ${proxysql}virtual_sender_mailbox_maps.cf
smtpd_sender_restrictions =
    reject_sender_login_mismatch,
    permit_sasl_authenticated,
    permit
Oleg Kr
  • 111
  • 2