Postfix & Keepalived for Outbound IP Availability

tested on slackware current (nov 2021)

Architecture

what matters most for an relay / mail-forwarder / outbound MTA is its SMTP client IP reputation, esp. when talking to google and microsoft mail exchangers.

for that matter, we need to think not only about making the relay service highly available, but we also need to handle the outbound traffic originating source.

Postfix setup

just proceed as with a normal relay but on TWO nodes, here postfix1 and postfix2. the difference here is that we rather have a public relay with ACLs, and also absolutely need to listen on all interfaces so the VRRP virtual IPs become served by it.

inet_interfaces = all

mynetworks = 127.0.0.1/32,
    192.168.122.0/24

Keepalived setup

install Keepalived somehow e.g.

all nodes

sbopkg -i keepalived

–or–

wget https://lab.nethence.com/slackpkgs/keepalived-2.2.4-x86_64-1_SBo.tgz
installpkg --terse keepalived-*.tgz

now setup a virtual default route with the src definition. we’re assuming you’ve got a default route on the same subnet as the virtual IP will get, already.

postfix1

    # we may restart the daemon at some point but that should take less than 10 seconds
    vrrp_script check-postfix {
            script "/sbin/pidof master"
            interval 5
            fall 2
            rise 1
    }

vrrp_instance MTA {
        state BACKUP
        interface xenbr0
        virtual_router_id 225
        priority 1
        advert_int 1

        # default route originates from virtual ip
        virtual_ipaddress {
                192.168.122.225/24
        }
        virtual_routes {
               default via 192.168.122.1 src 192.168.122.225 dev xenbr0
        }
            track_script {
                    check-postfix
            }

        notify "/var/tmp/notify.bash"
}

cat > /var/tmp/notify.bash <<EOF
#!/bin/bash
echo `date` -- $HOSTNAME received $@ >> /var/tmp/keepalive.log
EOF
chmod +x /var/tmp/notify.bash

Ready to go

replicate the confs across the farm

scp /etc/postfix/main.cf postfix2:/etc/postfix/
scp /etc/keepalived/keepalived.conf postfix2:/etc/keepalived/
scp /var/tmp/notify.bash postfix2:/var/tmp/
scp /etc/rc.d/rc.local postfix2:/etc/rc.d/

postfix1

ls -lF /etc/rc.d/rc.postfix # already enabled
grep rc.postfix /etc/rc.d/rc.M
vi /etc/rc.d/rc.local

# keepalived
sysctl -w net.ipv4.ip_nonlocal_bind=1
/usr/sbin/keepalived --log-detail

Maintenance

status

tail -n0 -F /var/log/* /var/tmp/keepalive.log
ip addr show xenbr0 | grep 'inet '
ip route | grep ^default
mailq

restart

rc.postfix restart

pkill keepalived
keepalived --log-detail

Acceptance

inbound service failover

workstation

ping 192.168.122.225 25 -c1
telnet 192.168.122.225 25

postfix1

ip addr show xenbr0 # currently holds the VIP
pkill keepalived

postfix2

ip addr show xenbr0 # has taken over the VIP

workstation

ping 192.168.122.225 25 -c1
telnet 192.168.122.225 25

outbound ip origin

workstation

tcpdump -i virbr0 icmp

postfix2

ip route | grep ^default

gives two default gateways, with the prefered one at first

default via 192.168.122.1 dev xenbr0 proto keepalived src 192.168.122.225
default via 192.168.122.1 dev xenbr0

then try to ping the public network

ping -c1 opendns.com
ping -c1 opendns.com
ping -c1 opendns.com

workstation

==> always originates from virtual ip 192.168.122.225

Resources

outbound ip

If only src ip address in virtual route was changed then keepalived does not update virtual route after reloading config (old route will be in route table) #1390 https://github.com/acassen/keepalived/issues/1390

Outgoing traffic with virtualIP using Keepalived and Haproxy https://medium.com/@rajivsharma.2205/outgoing-traffic-with-virtualip-using-keepalived-and-haproxy-6fa5635dd4ec

transport

https://serverfault.com/questions/257637/postfix-to-relay-mails-to-other-smtp-for-particular-domain

https://www.linuxbabe.com/mail-server/postfix-transport-map-relay-map-flexible-email-delivery ==> relay:


HOME | GUIDES | LECTURES | LAB | SMTP HEALTH | HTML5 | CONTACT
Copyright © 2024 Pierre-Philipp Braun