Postfix Dovecot Sieve – How to Configure Forwarding and Sieve

dovecotmail-forwardingpostfixsieve

Let's suppose my domain at exampleserver.com.
I have following sieve rule:

require ["fileinto", "subaddress", "mailbox", "variables"];

if address :detail :matches "to" "*" {
set "folder" "${1}"; 
fileinto :create "INBOX.${folder}";
}

user@exampleserver.com wants mail forwarded to xxxxx@gmail.com. It is done via /etc/postfix/virtual as

user@exampleserver.com      xxxxx@gmail.com

The forwarding is perfectly good, but mail sent to user+Something@exampleserver.com is now forwarded to user+Something@gmail.com which is utterly wrong. How to fix it so sieved messages get redirected to xxxxx+Something@exampleserver.com?

Best Answer

Postfix' aliasing via virtual is performed before any sieve proceeding. Therefore you have to disable postfix aliasing completely and forward messages by dovecot's sieve only. There is number of modes address is compared against the pattern:

......
# rule:[gmailfwd1]
if header :is "to" "user@exampleserver.com"
{
  redirect "user@gmail.com";
}

# rule:[gmailfwd2]
if header :contains "to" "user"
{
  redirect "otheruser@gmail.com";
}

# rule:[gmailfwd3]
if header :regex "to" "user.*@exampleserver.com"
{
  redirect "otheruser@gmail.com";
}
......

header :is means the strict matching the whole recipient's address

header :contains means that any part of address is matching the string.

header :regex means that recipient's address is matching the regular expression.

Anyway you have to remember that sieve rules are checked from the top to the bottom until some rule will be matched. So you can reorder rules in some sequence where more specific cases will be catched and proceeded before any other unwanted rules.

P.S.

As stated in the dovecot's manual https://wiki.dovecot.org/Pigeonhole/Sieve/Examples#Plus_Addressed_mail_filtering all can be made this way:

require ["variables", "fileinto", "subaddress"];

if header :is :user "to" "someuser" {
  if header :matches :detail "to" "*" {
    set "tag" "${1}";  /* extract "Something" into var "tag" */
  }

  if string :is "${tag}" "" { /* empty/no tag */
    redirect "user@gmail.com";
  } else {                    /* tag is present*/
    redirect "otheruser+${tag}@exampleserver.com";
  }
}
Related Topic