11

I have a postfix server correctly configured to allow incoming mail to my domain, and to require authentication in order to send mail to any other network.

A lot of spam that I get has a forged "from" address of non-existent users at my own domain. SPF could stop this, and I have SPF configured in my DNS, but I'm not sure I want to go the route of fully blocking all SPF fails at the SMTP level.

Is there a quick postfix configuration item I can add that would reject incoming email which is FROM mydomain and wasn't authenticated?

To be very specific, this is my postfix conf:

smtpd_relay_restrictions = permit_sasl_authenticated, reject_unauth_destination
smtpd_recipient_restrictions =
    permit_sasl_authenticated,
    reject_invalid_hostname,
    reject_non_fqdn_hostname,
    reject_non_fqdn_sender,
    reject_non_fqdn_recipient,
    reject_unknown_sender_domain,
    reject_unknown_recipient_domain,
    reject_rhsbl_sender dbl.spamhaus.org,
    permit
smtpd_sender_restrictions = reject_unknown_sender_domain
smtpd_helo_restrictions = reject_unknown_helo_hostname, reject_invalid_helo_hostname

yet it is still possible to connect to port 25 and

MAIL FROM: [email protected] RCPT TO: [email protected] without authenticating.

4 Answers 4

12

If you enable Postfix's message submission service (on port 587), you can separate "message submission from message relay, allowing each service to operate according to its own rules (for security, policy, etc.)" (RFC 4409).

Under this configuration, since legitimate users must authenticate to use port 587 for message submission, you can safely reject spoofed, unauthenticated mail submitted via port 25.

To enable (SASL-authenticated) message submission on port 587, add a section like the following to Postfix's master.cf:

submission inet n - n - - smtpd
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_sasl_type=dovecot
  -o smtpd_sasl_path=private/auth
  -o smtpd_sasl_security_options=noanonymous
  -o smtpd_sasl_local_domain=$myhostname
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o smtpd_sender_login_maps=hash:/etc/postfix/virtual
  -o smtpd_sender_restrictions=reject_sender_login_mismatch
  -o smtpd_recipient_restrictions=reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_sasl_authenticated,reject

(Source)

Then, create a Postfix access table (at /etc/postfix/access) specifying how Postfix should respond to certain senders:

[email protected]    OK
[email protected]            HOLD
mydomain.com                               REJECT

See the access man page for details.

Run postmap on the access file (to create an indexed lookup table):

postmap /etc/postfix/access

Add appropriate sender restrictions to main.cf:

smtpd_sender_restrictions = permit_sasl_authenticated,
        check_sender_access hash:/etc/postfix/access

Finally, reload the new configuration. On Debian-based systems, this is done using:

sudo service postfix reload
1
  • This was helpful and works - thank you. +1. Do you have any idea how to do this if the domains are held in a mysql table? I could write them out manually as above, but would have to edit the file each time all the virtual domains changed.
    – B. Shea
    Commented Sep 26, 2023 at 13:53
7

Is there a quick postfix configuration item I can add that would reject incoming email which is FROM mydomain and wasn't authenticated?

Not so quick, but you could implement a simple SMTPd Policy and pick the sender and sasl_username and check whether the first one comes from your domain and the second one exists and also comes from your domain, if so, return DUNNO, otherwise, REJECT. This way you ensure that for any incoming mail, if it is from your users, it must be SASL authenticated.

To be very specific, this is my postfix conf:

There are some additional items you can add to your smtpd_recipient_restrictions policy to try to stop the spam and at the same time improve your security:

smtpd_sender_restrictions =
    permit_mynetworks
    reject_unknown_sender_domain
    reject_sender_login_mismatch
    reject_unauth_pipelining
    reject_non_fqdn_sender
    permit

What means each might be found in the Postfix Configuration Parameters page.

There are some additional items you might want to include to stop the spam:

  • SPF is one of them, but I agree that blocking any non-matching test is quite heavy bearing in mind that some poorly implemented mail lists send e-mails with the original sender address from their servers so they fail.

  • DKIM is very powerful as well (check OpenDKIM).

  • SpamAssassin might be very helpful in this case. It won't block mail, but it will be added a Spam header and consequently be classified so.

  • You didn't provide a Postfix message of one of those spoofed attempts, but you could check if they are originated from the same IP address or at least a concrete CIDR address and put them into a blacklist with the smtpd_client_restrictions parameter.

  • Same may be applied to the HELO/EHLO message and might be placed into smtpd_helo_restrictions.

As you can see, there are a lot of ways, maybe you are able to find a combination of them that suits your case and stop all the spoofed attempts.

3
  • Do you have a working example of what that policy would look like? I get a lot of spam from senders who pass Received-SPF but include a fake From that includes a legit email @mydomain.com
    – user4043
    Commented Feb 1, 2019 at 6:08
  • This isn't an answer to specific OP question. They aren't worried about 'spam' in general - just spoofed local domains on unauthenticated 'incoming' emails. The approved answer works and answers the question although I wish there was a more streamlined postfix directive to use. Directing people to manuals isn't an answer. None of your recipient directives answers the question. So, how is this an answer? More like hints and non-answers.
    – B. Shea
    Commented Sep 26, 2023 at 18:36
  • @B.Shea 8 upvotes, 1 downvote (presumably you)... make your own conclusions.
    – nKn
    Commented Sep 28, 2023 at 7:31
1

I found one way to solve it, though I'm curious if anyone has a more direct/simple answer.

I used the reject_sender_login_mismatch setting so that if postfix can find a mapping from "FROM" address to a username, it requires that that user name be authenticated.

Then, the task is to build a map which handles all addresses @mydomain but which correctly lets local users send mail for their address.

On my particular configuration, I use

virtual_alias_maps = sqlite:/etc/postfix/db-public-alias.cf pcre:/etc/postfix/db-public-alias-regex.cf

to map addresses to actual users.

I added another address database pcre:/etc/postfix/db-sender-logins-fallback.cf which has a regex from all my domains to my main user. So now when combined:

smtpd_sender_login_maps = sqlite:/etc/postfix/db-public-alias.cf pcre:/etc/postfix/db-public-alias-regex.cf pcre:/etc/postfix/db-sender-logins-fallback.cf
smtpd_sender_restrictions = reject_unknown_sender_domain, reject_sender_login_mismatch

every alias can only be sent from the user it is routed to, and every other address at my domains can only be sent from my main user account, and so any spammer trying to send FROM: my domain will fail because they aren't logged in as me.

While this is a nice improvement to my mail setup (local users can no longer impersonate eachother) it could be too complicated for people with very advanced user account configurations. I'm still curious if there is a way to just say "for these domains in FROM:, user must be logged in".

3
  • reject_sender_login_mismatch did not work for me Commented May 15, 2019 at 10:52
  • @usr-local-ΕΨΗΕΛΩΝ perhaps you didn't quite solve the part of mapping all possible addresses to a username? It worked for me but I do recommend one of the other two solutions above; particularly the port 587 mechanism, which I assume any larger organization would want to do anyway.
    – dataless
    Commented May 16, 2019 at 17:50
  • Yes, looks like the 587 port trick is now working. I agree with you Commented May 17, 2019 at 9:38
0

My conf authentication section. Works well:

smtpd_sender_restrictions =
 reject_non_fqdn_sender
 reject_sender_login_mismatch
 reject_unknown_sender_domain
 reject_unauth_pipelining
 reject_non_fqdn_sender
 reject_unlisted_sender
 reject_unverified_sender
 permit_sasl_authenticated
 reject_unknown_reverse_client_hostname
 reject_unknown_client_hostname

smtpd_recipient_restrictions =
 permit_sasl_authenticated
 reject_unauth_destination
 reject_rbl_client            zen.spamhaus.org
 reject_rhsbl_reverse_client  dbl.spamhaus.org
 reject_rhsbl_helo            dbl.spamhaus.org
 reject_rhsbl_sender          dbl.spamhaus.org

smtpd_relay_restrictions =
 permit_sasl_authenticated
 reject_unauth_destination

smtpd_helo_required = yes
smtpd_helo_restrictions =
 permit_sasl_authenticated
 reject_invalid_helo_hostname
 reject_non_fqdn_helo_hostname
 reject_unknown_helo_hostname
2
  • 1
    It would be helpful to surround your code by some explanation.
    – zx485
    Commented Sep 25, 2019 at 18:04
  • This is not an answer. Nor in any form to be able to derive an answer.
    – B. Shea
    Commented Sep 26, 2023 at 13:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .