HAProxy for Mailloadbalancing


#1

Hello everyone,

I want to use the HAproxy for loadbalancing incoming Mails to two Mailserver.
My chellange now is, that no mail may be discarded.
So can you help me to set up the haproxy, so that he is checking every time the availability of the mailserver while trying to forward a mail to him. That means also it isen’t enough to check every second if the mailserver is availabel. He has to check everytime he have to send an mail, if the mailserver is reachable. And if not to try to send the mail to the other mailserver.

Kind regards
Bela


#2

Hi Bela,

You may try below haproxy configuration to achieve load-balancing of incoming SMTP connections.

defaults
    log global
    option tcplog
    option dontlognull
    option redispatch
    retries 3
    timeout http-request 10s
    timeout http-keep-alive 10s
    timeout check 10s
    timeout server 10s
    timeout connect 10s
    timeout client 10s
 
listen stats
	bind *:9999
    mode http
    stats enable
    stats hide-version
    stats uri /stats
	stats auth admin:admin@123
 
listen mailsmtp
    bind *:25
	mode tcp
    no option http-server-close
    balance roundrobin
    option smtpchk HELO mail.example.org ##mail.example.org is the domain name presented to the server. By default localhost is used.
    default-server inter 10000 fall 1 rise 2 downinter 1000 
	server mailserver1 xxx.xxx.xxx.xxx:25 send-proxy check
    server mailserver2 yyy.yyy.yyy.yyy:25 send-proxy check

To summarize the set-up, I have two mail servers mailserver1 and mailserver2. Health of both the mail servers are periodically checked using smtpchk keyword which consist of creating a TCP connection followed by issuing an SMTP command. The server’s return code is then analysed to infer its health.
Also, very often the backend mail servers require the client IP to perform various operations such as spam filtering and anti-spoofing on incoming mails. Therefore, we used send-proxy keyword so that HAProxy ensures that the client IP is forwarded to backend servers.
Other keywords used are:

  • inter : Interval between 2 consecutive health checks.
  • fall : The number of consecutive health check failures after which a server would be marked as DOWN.
  • rise : The number of consecutive health check successes after which a server which was previously DOWN would be marked as UP.
  • downinter: The interval between 2 consecutive health checks when a server is in DOWN state.

WORST CASE SCENARIO:
HAProxy performed a check at 00:00:00 GMT and both the mail servers were found to be UP. The next health check would therefore be performed at 00:00:10 GMT. However, just after the first successful health check, mailserver1 started crashing and at that very moment, coincidentally, an email arrived and HAProxy forwarded that email to mailserver1. What would be the fate of that email?

As per above configuration, if an incoming mail is forwarded to a deteriorating mail server, mailserver1 in this case, and the connection request to that mail server fails then 3 retires are performed at an interval of 10 seconds each (timeout connect 10s). Also, since redispatch is enabled, the last retry would be performed on a different server which is in good health. Therefore, the chances of a mail getting discarded due to a bad server are quite bleak.

Hope this is helpful !


#3

Also, unless the sender has seen a SMTP “250” message, it will consider the email not delivered, therefor retrying later, on a different SMTP server or report the failure back to the client.

The entire SMTP protocol has been designed to avoid loosing emails in transit and usually you do not even need any load-balancers at all (unless are talking about the customer facing SMTP).

Both for the MX SMTP case and for the customer facing SMTP as well, always make sure you understand how a failure propagates back to the users or sending MTA and make sure you do not over engineer your setup.

KISS.