6

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: foo@mydomain.com RCPT TO: bar@mydomain.com without authenticating.

6

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:

allow_this_for_some_reason@mydomain.com    OK
keep_in_hold_queue@mydomain.com            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
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.

  • 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 – g33kz0r Feb 1 at 6:08
0

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".

  • reject_sender_login_mismatch did not work for me – usr-local-ΕΨΗΕΛΩΝ May 15 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 May 16 at 17:50
  • Yes, looks like the 587 port trick is now working. I agree with you – usr-local-ΕΨΗΕΛΩΝ May 17 at 9:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.