Backup MX Server

Posted on 16 2026

A backup MX server accepts inbound mail when the primary mail server is unreachable and queues it until the primary comes back online. Without one, sending mail servers retry delivery for a period (typically up to five days) before bouncing the message. With a backup MX, mail is accepted and queued locally, eliminating the risk of bounce during planned or unplanned downtime.

For this three-site network, the backup MX opportunity is built into the existing architecture. The secondary sites each have a server capable of running a lightweight Postfix instance as a backup relay. Using one of the secondary site servers means the backup MX is geographically separated from the primary, connected via the inter-site WireGuard VPN, and already part of the managed infrastructure.

How backup MX works

When a sending mail server looks up the MX records for a domain, it sees a list ordered by priority. Lower priority numbers are tried first. If the primary server (priority 10) is unreachable, the sending server tries the next MX record (priority 20). The backup MX accepts the message, holds it in its queue, and periodically attempts delivery to the primary server.

When the primary recovers, the backup server’s queue drains automatically: Postfix retries all queued messages on its normal retry schedule.

The backup MX does not process, filter, or deliver mail to mailboxes. It only holds and relays.

DNS records

Add a second MX record to the public DNS zone with a higher priority number than the primary:

; Primary mail server (highest priority - lower number)
yourdomain.net.    IN    MX    10    mail.yourdomain.net.

; Backup mail server (lower priority - higher number)
yourdomain.net.    IN    MX    20    mail-backup.yourdomain.net.

Add an A record for the backup MX hostname pointing at the secondary site’s public IP:

; Backup mail server hostname
mail-backup.yourdomain.net.    IN    A       secondary.site.wan.ip
mail-backup.yourdomain.net.    IN    AAAA    secondary::site::ipv6

The backup MX must also have a valid PTR (reverse DNS) record, just like the primary. Contact the ISP at the secondary site to set this up.

Container setup on the secondary site

Clone the base container template on the secondary site’s Proxmox host:

pct clone 100 110 --hostname mail-backup --full
pct start 110

Inside the container:

hostnamectl set-hostname mail-backup.yourdomain.net
sed -i 's/base-template/mail-backup/g' /etc/hosts

Installing Postfix as a backup relay

sudo apt install -y postfix

During installation, select Internet Site and enter mail-backup.yourdomain.net as the system mail name.

Postfix backup MX configuration

The backup MX configuration is deliberately minimal. It accepts mail for the hosted domains, holds it in the queue, and relays it to the primary server. It does not deliver to local mailboxes.

Edit /etc/postfix/main.cf:

sudo postconf compatibility_level=3.6
sudo postconf myhostname=mail-backup.yourdomain.net
sudo postconf mydomain=yourdomain.net
sudo postconf myorigin='$mydomain'

# Accept mail for these domains (as backup MX)
sudo postconf "relay_domains=yourdomain.net"

# Relay accepted mail to the primary mail server
# Using the internal VPN address for secure delivery
sudo postconf "relay_transport=smtp"
sudo postconf "transport_maps=hash:/etc/postfix/transport"

# Only accept mail from external servers, not generate local mail
sudo postconf mydestination=
sudo postconf local_recipient_maps=

# Network interfaces to listen on
sudo postconf inet_interfaces=all
sudo postconf inet_protocols=all

# Restrict relaying to backup MX role only
sudo postconf "smtpd_recipient_restrictions=reject_unauth_destination"

Transport map

Create /etc/postfix/transport to route accepted mail to the primary server via the VPN:

yourdomain.net    smtp:[10.1.0.12]:25

Replace 10.1.0.12 with the primary mail server’s internal VPN address. Using the internal VPN address ensures delivery between sites is encrypted and does not traverse the public internet.

Build the transport database:

sudo postmap /etc/postfix/transport

Recipient validation

Without recipient validation, the backup MX accepts mail for any address at the hosted domain. This means if a spammer sends to random-invalid@yourdomain.net, the backup MX accepts it and the primary server subsequently rejects it, generating a backscatter bounce. Recipient validation prevents this.

Configure Postfix to check recipients against the primary server before accepting:

sudo postconf "smtpd_recipient_restrictions=reject_unauth_destination, check_recipient_access hash:/etc/postfix/relay_recipients"

Create /etc/postfix/relay_recipients listing valid recipients:

you@yourdomain.net       OK
admin@yourdomain.net     OK
postmaster@yourdomain.net OK

Build the database:

sudo postmap /etc/postfix/relay_recipients

This approach requires manually maintaining the recipient list. An alternative is to query the primary server’s PostfixAdmin database directly, which requires network access to the database and is covered in the advanced Postfix configuration section.

SMTP restrictions

Add restrictions to prevent the backup MX from being used as an open relay:

sudo tee /etc/postfix/main.cf >> << 'EOF'

# Anti-spam: reject clearly invalid senders
smtpd_sender_restrictions =
    reject_non_fqdn_sender,
    reject_unknown_sender_domain

# Require FQDN in HELO/EHLO
smtpd_helo_required = yes
smtpd_helo_restrictions =
    reject_invalid_helo_hostname,
    reject_non_fqdn_helo_hostname

EOF

TLS configuration

The backup MX should support TLS for inbound connections. If a Let’s Encrypt certificate is available for mail-backup.yourdomain.net:

sudo postconf smtpd_tls_security_level=may
sudo postconf smtpd_tls_cert_file=/etc/letsencrypt/live/mail-backup.yourdomain.net/fullchain.pem
sudo postconf smtpd_tls_key_file=/etc/letsencrypt/live/mail-backup.yourdomain.net/privkey.pem
sudo postconf smtpd_tls_loglevel=1
sudo postconf smtp_tls_security_level=may
sudo postconf smtp_tls_loglevel=1

Start Postfix

sudo systemctl enable --now postfix

Verify the configuration:

sudo postfix check
sudo postfix status

Firewall rules

The backup MX needs port 25 (SMTP) open to the internet for inbound mail delivery. Add a port forward on the secondary site’s router pointing at the backup MX container, and a firewall rule permitting inbound TCP on port 25.

On the UniFi gateway at the secondary site, add a port forward identical to the one on the primary site router, but pointing at the backup MX container’s internal address.

On the homelab server firewall:

sudo ufw allow 25/tcp

SPF record update

Add the backup MX server to the SPF record so mail relayed from it to the primary is not rejected:

yourdomain.net.    IN    TXT    "v=spf1 mx a:mail.yourdomain.net a:mail-backup.yourdomain.net -all"

The mx mechanism already includes both MX record targets, but adding the explicit a: record ensures coverage even if SPF resolvers handle the mx mechanism inconsistently.

Testing the backup MX

Test basic acceptance

From an external machine or mobile hotspot, test that the backup MX accepts mail:

nc -v mail-backup.yourdomain.net 25

The backup MX should respond with its SMTP banner. Send a test message:

EHLO test.example.com
MAIL FROM:<test@external.example.com>
RCPT TO:<you@yourdomain.net>
DATA
Subject: Backup MX test

Testing the backup MX relay.
.
QUIT

Check the Postfix queue on the backup MX:

sudo mailq

The message should appear in the queue destined for the primary server’s VPN address.

Test failover behaviour

With the primary mail server stopped, send a test message to your address from an external mail service. The message should be accepted by the backup MX.

Start the primary mail server again. The backup MX should flush its queue within a few minutes, delivering the held messages.

# Force a queue flush on the backup MX
sudo postqueue -f

Monitoring the backup MX queue

An unexpectedly large queue on the backup MX indicates either the primary server is down or the delivery route between sites has a problem. Add queue monitoring to the alerting setup:

cat > /etc/cron.hourly/check-mail-queue << 'EOF'
#!/usr/bin/env bash
# Alert if backup MX queue exceeds threshold
QUEUE_SIZE=$(mailq | grep -c "^[A-F0-9]")
THRESHOLD=50

if [ "$QUEUE_SIZE" -gt "$THRESHOLD" ]; then
    echo "Backup MX queue has $QUEUE_SIZE messages. Primary server may be down." | \
        mail -s "Backup MX queue alert on $(hostname -s)" root
fi
EOF

chmod 0755 /etc/cron.hourly/check-mail-queue

Alternative: commercial backup MX

For a home network where running infrastructure at a secondary site is impractical, several commercial services provide backup MX for low cost or free:

  • Rollernet: reliable secondary MX with queue times up to three weeks
  • MXroute: low-cost mail hosting that can also serve as backup MX
  • Cloudflare Email Routing: free, but limited to forwarding rather than true backup queuing

These are reasonable alternatives if the three-site architecture is not fully operational yet. The self-hosted approach above is preferable once all three sites are running.

A backup MX that accepts mail for invalid recipients generates backscatter bounces that damage the domain’s reputation. The recipient validation step is not optional. Even a static list of valid recipients is significantly better than accepting all mail and having the primary bounce invalid addresses.


Roll Your Own Network / Server / Mail. Next: Postfix MTA.