March 01, 2018How to convert string permissions to numeric
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 word
OK, so each line would be:
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 the
[primary] scp /etc/postfix/virtual email@example.com:~ [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 format
domain.com=1234567890, 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 firstname.lastname@example.org:~ [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/id_rsa.pub email@example.com
Enter the remote password. All done.
Now we need to create the scripts:
[primary] vi /home/user/backupmx.sh
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:
#!/bin/sh # postfix/vmin backup mx file 1/2 (primary) # copy virtual (valid email addresses) if test /etc/postfix/virtual -nt /home/user/virtual then cp /etc/postfix/virtual /home/user/virtual scp /home/user/virtual firstname.lastname@example.org:~ fi # copy map.dom (list of domains) if test /etc/webmin/virtual-server/map.dom -nt /home/user/map.dom then cp /etc/webmin/virtual-server/map.dom /home/user/map.dom sed -i 's/=/ /g' /home/user/map.dom scp /home/user/map.dom email@example.com:~ fi
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/backupmx.sh
And paste in:
#!/bin/sh # postfix/vmin backup mx file 2/2 (backup) # copy virtual (valid email addresses) if test /home/user/virtual -nt /etc/postfix/relay_recipients then cp /home/user/virtual /etc/postfix/relay_recipients /usr/sbin/postmap /etc/postfix/relay_recipients /usr/sbin/postfix reload fi # copy map.dom (list of domains) if test /home/user/map.dom -nt /etc/postfix/relay_domains then cp /home/user/map.dom /etc/postfix/relay_domains /usr/sbin/postmap /etc/postfix/relay_domains /usr/sbin/postfix reload fi
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/backupmx.sh
Do the same on the backup computer.
Voila. Automated secondary mail server.