There are various guides online for setting up Postfix as a backup (hold and forward) mail server, which knows which accounts are valid on the primary (to prevent backscatter spam, so it only accepts emails for actual accounts on the primary mail server). All of them are slightly different, and none of them worked out of the box for me. This is how I did it – this method is facilitated by using Virtualmin on the primary since it has already generated map files that we can use.

We need two files on the backup mail server: a list of domains to relay and a list of valid email accounts. With a little tweaking, we can copy a couple of Virtualmin configuration files over from the primary, and the backup will automatically know what the valid accounts are.

Note: if you’re using Virtualmin, make sure your alias domains are copying the accounts from the domain they are aliasing rather than running a catch-all domain (which is the default setting); otherwise, it rather defeats the purpose of specifying the valid accounts. To set this up on future-created domains, go to System Settings, Server Templates, select your template(s), go to Mail for a domain, and change “Mail alias mode for alias domains” to “Copy aliases from target” and Save. If you have existing catch-all alias domains, if you select that domain and go to Server Configuration, Email Settings, you can change the Mail aliases mode.

So, back to those two files. They need to be files that Postfix can map into a hash file for itself to use. The standard way of doing this is to have the domain (or email address) and then space and then the wordOK, so each line would be: OK

However, the second part can be anything for the hash to work, it doesn’t have to be, and Virtualmin creates a virtual mapping file that maps email addresses to accounts that we can use as an excellent relay recipient list. The data is at/etc/postfix/virtualso the first step is to copy that file to the backup as/etc/postfix/relay_recipients. (This will all need to be done as therootuser.)

[primary] scp /etc/postfix/virtual
[backup] cp /home/user/virtual /etc/postfix/relay_recipients

Then we need to tell Postfix to use those email addresses, so as root:

[backup] postmap /etc/postfix/relay_recipients

If that fails, you may need to adjust the permissions of/etc/postfixso that it can create the .db file (and then rerun the command):

[backup] chmod 777 /etc/postfix
[backup] postmap /etc/postfix/relay_recipients

Then update the Postfix configuration and reload it:

[backup] postconf -e "relay_recipient_maps = hash:/etc/postfix/relay_recipients"
[backup] postfix reload

Next, we need a list of valid domains to relay. Virtualmin does create a map of domains for itself with the, so all we need to do it replace the equals sign with space, and we have a valid map file.

[primary] scp /etc/webmin/virtual-server/map.dom
[backup] sed -i 's/=/ /g' /home/user/map.dom
[backup] cp /home/user/map.dom /etc/postfix/relay_domains

Then similar to above, update the config and reload:

[backup] postmap /etc/postfix/relay_domains
[backup] postconf -e "relay_domains = hash:/etc/postfix/relay_domains"
[backup] postfix reload

That’s it! If there were no problems, they are now in sync.

You don’t want to have to do this manually each time, so we need to set up an ssh key-pair so that you don’t have to enter your password and then create scripts that we will run automatically every few minutes to retain the sync.

Creating a passwordless key-pair is pretty simple. Type in:

[primary] ssh-keygen -t rsa

Use the default info and no password. Then copy to the backup:

[primary] ssh-copy-id -i ~/.ssh/

Enter the remote password. All done.

Now we need to create the scripts:

[primary] vi /home/user/

What we’ll do is check if Virtualmin’s files are newer than the ones we last copied to the backup and, if so, then copy over the original data (having updated the domain map). So paste in:

# postfix/vmin backup mx file 1/2 (primary)
# copy virtual (valid email addresses)
 if test /etc/postfix/virtual -nt /home/user/virtual
  cp /etc/postfix/virtual /home/user/virtual
  scp /home/user/virtual
# copy map.dom (list of domains)
 if test /etc/webmin/virtual-server/map.dom -nt /home/user/map.dom
  cp /etc/webmin/virtual-server/map.dom /home/user/map.dom
  sed -i 's/=/ /g' /home/user/map.dom
  scp /home/user/map.dom

And a similar script on the backup – check if the files are newer and if so, copy them and update the config:

[backup] vi /home/user/

And paste in:

# postfix/vmin backup mx file 2/2 (backup)
# copy virtual (valid email addresses)
 if test /home/user/virtual -nt /etc/postfix/relay_recipients
  cp /home/user/virtual /etc/postfix/relay_recipients
  /usr/sbin/postmap /etc/postfix/relay_recipients
  /usr/sbin/postfix reload
# copy map.dom (list of domains)
 if test /home/user/map.dom -nt /etc/postfix/relay_domains
  cp /home/user/map.dom /etc/postfix/relay_domains
  /usr/sbin/postmap /etc/postfix/relay_domains
  /usr/sbin/postfix reload

Then add those files to the cron on both systems

[primary] crontab -e

And add the line (to run every 5 minutes):

*/5 * * * * /home/user/

Do the same on the backup computer.

Voila. Automated secondary mail server.


Sr. Software Engineer with over 10 years of experience. Hobbist photographer and mechanic. Tinkering soul in an endeavor to better understand this world. Love traveling, drinking coffee, and investments.

You may also like

LUKS Drive Encryption
Removing Linux User

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: