I had a tough problem. I have previously set up mail forwarding for an alias in one of the domains I host. However, the forwarding used the original sender's envelope address.

Why is that a problem? Because of SPAM. Because my server is not authorized to send on behalf of other folks' domains, and some domains have restrictive policies that inform other servers not to accept e-mail from their domain unless it comes from the designated host.

So I thought, never mind, maybe there's an easy workaround: instead of an alias, I set up a virtual Dovecot mailbox and use procmail.

But how? Procmail is not invoked when Dovecot delivers the e-mail to the virtual mailbox, so I was stuck. My beautifully crafted .procmail forwarding rule was for naught.

At this point, I solicited the help of our AI friends. Long story short, none of the suggestions they (GPT-4, GPT-3.5, Claude) offered worked, but they informed me of a Dovecot extension called sieve, which allows for the post-processing of e-mails in virtual mailboxes (and which, in a number of ways, is actually superior to procmail).

OK, I implemented that, and the forwarding worked... except that the envelope address was still that of the original sender. Grrr!

But then, reading the sieve documentation, I finally stumbled upon the final piece of the puzzle: a system-level configuration setting for sieve in Dovecot. May not be appropriate for everyone but in my case, it did the trick.

So then, the main steps of how I implemented this (recording it here for posterity so that I will know myself next time what to do!) are these:

  1. I had an alias set up as a sendmail alias file with the actual e-mail addresses.
  2. I created a virtual user in Dovecot the usual way, along with the corresponding vmail folder. I removed any previous occurrences of that virtual user from the sendmail virtusertable file. I created a sieve subfolder, in which I placed the following file named redirect.sieve:
    if not anyof (
      header :contains ["from"] ["MAILER-DAEMON"],
      header :contains ["auto-submitted"] ["failure"]
    ) {
      redirect "alias-address@localhost";

    The conditionals were there to avoid a mail loop in case of error. I created a soft link from redirect.sieve to .dovecot.sieve in the virtual user's home directory.
  3. Most importantly: In /etc/dovecot/conf.d/90-sieve.conf, I added the line

        sieve_redirect_envelope_from = orig_recipient

    It is this line that ensures that the correct envelope sender is used in the forwarded e-mails.

This is pretty much it. I had some additional housekeeping to do because I also had additional checks to ensure that only authorized folks could send messages to these lists, so now I had to add the list address itself to the list, because the list can now send messages to itself.

Some relevant links: