I've a postfix email server running and everything was fine... well until someone decided to impersonate other users. The current situation is:

  • user1@mydomain.dev can send email with a faked from header saying it is user2@mydomain.dev;

At the faked emails headers I can see this:

From: User2 <user2@mydomain.dev>

(Authenticated sender: user1@mydomain.dev)

Clearly the user is using it's legit email address / password to authenticate on the server and then sets the From header to the user he wants to impersonate.

I've tested this myself and it works. However, if I change the domain to some domain not on the virtual domains table the email client says the server refused the email.

Is there a way I can make sure user1@mydomain.dev is only able to send emails with from header matching his email and not someone else on virtual domains table? -- Give an error like it happens when the domain is not listed.

My current smtpd restrictions are:

smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, reject_unauth_pipelining, reject_unknown_sender_domain, reject_unknown_recipient_domain

smtpd_client_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_invalid_hostname, reject_rbl_client zen.spamhaus.org, reject_rbl_client bl.spamcop.net, reject_rbl_client cbl.abuseat.org

smtpd_sender_restrictions = permit_mynetworks, reject_unknown_address, reject_unknown_sender_domain, reject_non_fqdn_sender

Note: On the server there is plus addressing (ex. user1+something@ mydomain.dev will deliver emails to user1@mydomain.dev) and also a virtual alias maps. For someone posting a solution to the problem above can you make sure the user is still able to "impersonate" is own emails based on plus-addressing or aliases. I need then to be able to send from user1+something@mydomain.dev or alias-f1@mydomain.dev (only if they belong to them).

Thank you.

  • 2
    You might be able to set something up using the reject_authenticated_sender_login_mismatch as part of your smtpd_sender_restrictions. Haven't tried it, though. – tarleb Jan 25 '16 at 10:40
  • Well after reject_authenticated_sender_login_mismatch I always get 5.7.1 <user1@mydomain.dev>: Sender address rejected: not owned by user user1@mydomain.dev”. Maybe I've to set smtpd_sender_login_maps as well, so it can tell postfix witch users can't send? @tarleb – TCB13 Jan 25 '16 at 12:19
  • But... smtpd_sender_login_maps usually contains something like user1@mydomain.dev user1 establishing a relationship between (authenticated) users and message addresses. Can I just point this to the same thing as virtual_mailbox_maps and then maybe change the MySQL query to include alias as well? – TCB13 Jan 25 '16 at 12:28
  • @tarleb I managed to make it with your precious help (again). If you want just replay the question with this answer I've made pastebin.com/9dZ0wWgQ and I'll gladly accept it. Without your help I wasn't able to get to that solution. Thank you. – TCB13 Jan 25 '16 at 13:20
  • 1
    Great! Glad I could help. 😊 If you don't mind, just add a self-answer, I think you now know more in this matter than I do. – tarleb Jan 25 '16 at 13:25

With precious help from @tarleb (that pointed me on the right direction) I managed to come up with this solution:

  1. Add reject_sender_login_mismatch to the end of the smtpd_sender_restrictions section;
  2. Since I've virtual_mailbox_domains and virtual_alias_maps based on MySQL queries, add smtpd_sender_login_maps = mysql:/etc/postfix/mysql-virtual_sender-login-maps.cf. This is the maps used by postfix to make sure the sender login email and from field match;
  3. Create /etc/postfix/mysql-virtual_sender-login-maps.cf with the following content:

    user = emailserveruser
    password = sdfjn1234ns
    hosts =
    dbname = mailstack
    query = SELECT * FROM (SELECT email FROM `virtual_users` WHERE email = '%s' UNION SELECT destination FROM `virtual_alias` WHERE source = '%s' ) a

How does it work?

Postfix will give you the From email as %s and it excepts to receive as result of a query an address that matches the one used on the SMTP authentication.

In this case we first query the virtual_users table and if nothing is returned from there (meaning there's no real user with that email) we query virtual_alias in order to get the destination address (a real user mailbox) that matches a potential email alias (our source field).

If there's no match, the query returns nothing, it means that: 1) there's no such user with that email 2) there's no such alias to any user with that email -- Postfix then gives the mail client a Sender address rejected: not owned by user error.

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.