These are some short stepts and pointers to setup a postfix fallback MX. It does not describe postfix basics, nor how to install Mailscanner (a necessisity, because spammers like sending spam to fallback MX’s because they’re usually not as well protected).

First, postfix has a special transport, called ‘relay’, which is the same as SMTP, except that it doesn’t send to the backup MX. In this case, that means it doesn’t send to itself, avoiding loops. The relay transport is the default for all the domains you specify in the relay_domains parameter.

Should the machine have a relayhost defined, you need to disable that for each of the domains you’re a backup MX for. You can do that with transport_maps. In my case, the transport_maps is hash:/etc/postfix/transport_maps. That is a key-value file on which you run ‘postmap’ after you’ve edited it. In it, specify this (the comments explain it):

# When you specify a transport without nexthop, it resets the relay to the
# recipient domain (see man 5 transport). And, when the transport is relay,
# postfix will not relay to the backup MX, to prevent loops back to itself. So,
# because this host has a default relayhost, use the folowwing when you want to
# specify a domain for which we are backup MX: 
# example.com            relay 

The next step you want to do is take measures to prevent mails to non-existent users piling up in the queue. Because spam is sent to the backup MX all the time, it will relay it to the primary, which rejects it. Your backup host will then bounce all kinds of spam mails…

To fix that, we instruct postfix to use recipient address verification. This causes it to probe the primary host to check the address exists (and caches that info) before relaying.

To enable it, do this:

smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination, reject_unknown_recipient_domain, reject_unverified_recipient
unverified_recipient_reject_reason = Address lookup failed
# Prevent caching non-existent users, to prevent delivery failures when new users are unknown still.
address_verify_negative_cache = no
# Setting to 550 to make a reject a fatal error, not a defer.
unverified_recipient_reject_code = 550
# The point of a backup MX is to accept mail when the primary is down, so setting this prevents incoming mail being deferred when the address probe cannot be done.
# TODO: find out how to actually implement it, because it doesn't work; permit it not a valid option here.
#unverified_recipient_tempfail_action = permit 

The reject_unknown_recipient_domain prevents probes to domains that don’t exist.

Some extra options, not strictly related to being a backup MX:

smtpd_sender_restrictions = reject_unknown_sender_domain, reject_unknown_helo_hostname
unknown_address_reject_code = 550
# Override the default of 5 days, because the point of a backup MX is to keep it around for a while.
maximal_queue_lifetime = 21d