I'm migrating email from old Plesk installations to custom built Ubuntu server running iRedMail (postfix/amavisd/dovecot/etc).

I'm using postfixadmin to administrate all domains and a mysql backend. I've noticed that if I want to "alias" something or create a forward, I can not use an existing mailbox - so I can't copy over the Plesk-style "redirect with saved copy" feature.

I'm currently setting remote aliases via a database and using:

virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf

If there is a way to still use my database it would be ideal - even if I have to add some columns, and change the query.



I figured this out. Basically I need to modify the mysql table that saves the aliases so that it supports multiple aliases per address, making it possible to have delivery setup for both the local domain and a remote email.

This works so far, though I've heard that some people attempting this have gotten duplicate emails to the forwarded email account. So far, I have not experienced this.

I was using postfixadmin to manage the accounts, but it doesn't support this usage, so I've had to modify the source code, so that it both displays, edits and deletes aliases properly.

The main lesson here is that when using mysql a single key can be mapped to multiple results, by setting a new primary key i.e. "id" but keeping your postfix query logic the same. The multiple results returned are the same as multiple results in the default dbm/bd files, except that you must create a new record with the same key rather than a single key with some kind of delimited result.

HTH others!

This should work with any maps in mysql.

  • In other words, if this SQL query returns multiple values, all is kosher, store and forward works: query = SELECT destination FROM virtual_aliases WHERE source='%s'
    – Greg
    Nov 2 '14 at 3:37
  • Confusing to read - I understand understand it. Needs to be visualized somehow. Apr 20 '18 at 10:46

Do you have local accounts for all users?

I've used a .forward file with something like:

user@new-mail-server.example.com, \user

which forwards a copy and keeps a copy in the local spool as well.

  • I'm using mysql, and the domains do not have local accounts, only virtual mailboxes. Is there another way to do this using my database, ideally making use of: virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
    – FilmJ
    Sep 9 '09 at 5:32
  • This! Put it in the user's home folder, where the "user" in \user is the username. Before I was using virtual alias maps, which was really not right for my use case. Not only did I have to write them out like this: account@mydomain.org account@mydomain.org externalaccount@externaldomain.com and rehash and restart Postfix for every change, but you had to do it at the alias level! And I think it was kicking in before basic anti-spam rules. So of course we got our IP blocked by Outlook almost straight away. I am using the mail-stack-delivery package for Ubuntu 18.04. Mar 26 '20 at 21:16
  • \user did not work for me, I had to type the username. Also I have no , in there. Jul 2 '20 at 11:59

If you have virtual account defined in virtual_mailbox_maps, and you want to redirect AND keep message, you have to insert 2 aliases into alias map:

account@example.com redirect@anotherdomain.com
account@example.com account@example.com

And this syntax will redirect any mail to account@example.com to redirect@anotherdomain.com AND will check if you have user account@example.com in virtual_mailbox_maps, and if so - save it.

update Or you can even use (@Tim Heagele thanks for the comment)

account@example.com account@example.com redirect@anotherdomain.com 
  • 3
    it can be in one row: account@example.com account@example.com redirect@anotherdomain.com Feb 5 '17 at 9:35
  • Your solution work for me, but at the address "redirect@anotherdomain.com" i receive a duplicate copy of the message... any idea?
    – Pioz
    Aug 2 '17 at 10:19
  • It worked for by account@example.com redirect@anotherdomain.com,account@example.com. Thank you :)
    – tbutcaru
    Jan 24 '19 at 23:18

The very simple solution is to include the source address in a comma-separated list in the destination column. E.g.:

insert into virtual_aliases (domain_id, source, destination) 
values (1, 'account1@domain1.com', 'account1@domain1.com,account2@domain2.com');

That works for me.

  • That works for me too but at "account2@domain2.com" i receive a duplicate copy of the message... any idea?
    – Pioz
    Aug 2 '17 at 10:22

It's probably more kosher to dispatch from postfix' main.cf:

Say, in main.cf:

### let's archive some incoming/outgoing mail:
recipient_bcc_maps = hash:/etc/postfix/recipient-bcc
sender_bcc_maps    = hash:/etc/postfix/sender-bcc

and in the relevant files (recipient-bcc and sender-bcc) for example:

@sender.domain a.local@address

Don't forget to (re)build the databases after editing the files:

postmap hash:recipient-bcc
postmap hash:sender-bcc
  • 1
    So, I'm using mysql at the moment, so ideally I'd need to create something in the database - any ideas how to do this?
    – FilmJ
    Sep 9 '09 at 5:25

This question is quite old but I just ran into the same situation having the same environment (postfix; dovecot; mysql) and realised the following approach:

I created a new db table storing my virtual forward configurations:

CREATE TABLE `virtual_forwards` (
  `id` int(11) NOT NULL auto_increment,
  `domain_id` int(11) NOT NULL,
  `source` varchar(100) NOT NULL,
  `destination` varchar(100) NOT NULL,
  PRIMARY KEY (`id`),
  FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE

I then created a new virtual forward map file /etc/postfix/mysql-virtual-forward-maps.cf which queries the previously created virtual_forwards table AND always returns the concatenated source as well as destination address (mail will be sent to alias AND destination):

user = mailuser
password = <PASS>
hosts =
dbname = <DB_NAME>
query = SELECT CONCAT(source, ',', destination) FROM virtual_forwards WHERE source='%s'

And finally I added the new map file to my /etc/postfix/main.cf as virtual_alias_maps:

virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf,mysql:/etc/postfix/mysql-virtual-forward-maps.cf

Restart your postfix server and everything should work like expected. I favor this approach against adding a comma separated list to the virtual_aliases table since it just feels wrong for me. But that might be my personal problem :)

I'm aware of the fact that I can't add multiple forwards based on the same source address (e.g. test@tworabbits => test1@tworabbits, test2@tworabbits) but one could easily split the virtual_forwards table into virtual_forward_sources AND virtual_forward_destinations in order to satisfy that requirement.

I hope this helps somebody when another five years have passed :) Cheers!


The answers above are outdated, the solution is actually much simpler. You need to click on the "ALIAS" button, insert the email address to which you want emails be forwarded to, and click on "Deliver to the local mailbox." in order to tick it. If there's a tick there, emails will be delivered locally too.

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.