Назад | Перейти на главную страницу

Балансировка нагрузки SMTP с IP-адресом удаленного хоста, переданным на серверы SMTP?

Я пытаюсь построить SMTP-кластер с балансировкой нагрузки. Почтовые серверы уже существуют и работают с Exim 4. Первоначально я рассматривал использование Nginx для балансировки нагрузки, однако в тестовой системе все почтовые серверы видят входящие соединения как исходящие с IP-адреса балансировщика нагрузки, а не с фактического удаленного IP-адрес отправителя, и после обширного поиска в Google, похоже, нет никакого способа обойти это. Поскольку это эффективно превращает почтовый кластер в открытый ретранслятор, он явно не запускается, что очень жаль, поскольку в остальном Nginx прекрасно работает.

Поэтому я хочу использовать вместо этого HAProxy, поскольку я понял из дальнейшего поиска в Google, что он имеет возможность передавать соединения с исходным исходным IP-адресом без изменений, поэтому системные списки разрешения ретрансляции и ACL будут работать правильно.

Однако, настроив HAProxy в соответствии с несколькими онлайн-примерами, я либо получаю «ошибку синхронизации SMTP» (и ошибку серии 500, так что почта будет отскакивать), и соединение немедленно разрывается, либо просто разрывается соединение без сообщения SMTP вообще .

Вот используемый haproxy.conf:

global

    log         127.0.0.1 local2

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        nobody
    group       nobody
    daemon

    stats socket /var/lib/haproxy/stats

defaults
    log                     global
    option                  redispatch
    retries                 3
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout check           10s
    maxconn                 3000

listen smtp
    bind 0.0.0.0:25
    mode tcp
    no option http-server-close
    balance roundrobin
#    option smtpchk HELO smtp-in.example.com
    server smtp01 10.0.0.141:25 send-proxy check
    server smtp02 10.0.0.143:25 send-proxy check

Несмотря на наличие команды send-proxy, которую, как я понимаю, вы указываете haproxy, чтобы он проходил через исходный IP, журналы Exim'a выглядят следующим образом:

016-12-26 07:06:48 Ошибка синхронизации протокола SMTP (вход отправлен без ожидания приветствия): отклонено соединение от H = [10.0.0.150] input = "PROXY TCP4 10.0.0.150 10.0.0.143 40334 25 \ r \ nHELO smtp-in.example.comr \ n "

В этом случае .150 - это балансировщик нагрузки, а .143 - это SMTP-сервер Exim.

Вопросы:

  1. На самом деле возможно ли заставить Nginx представлять SMTP-соединения с почтовыми серверами с исходным IP-адресом, являющимся реальным удаленным исходным IP-адресом, а не балансировщиком нагрузки?

  2. В качестве альтернативы, возможно ли это в HAProxy и как это делается?

В этом случае текущая производственная система использует LVS, однако он полагается как на балансировщик нагрузки, так и на интерфейсы обратной связи на всех почтовых серверах, использующих один и тот же IP-адрес. Новым балансировщиком нагрузки будет OpenSUSE 42.2, и, среди прочего, если он обнаруживает IP-адрес, уже используемый в сети, он, по-видимому, услужливо удаляет его из себя, чтобы избежать конфликта. Итак, LVS отсутствует в новой сборке.

Другие решения проблемы, которые я рассматриваю, включают полное разделение входящего и исходящего SMTP-трафика (в настоящее время все работает через один и тот же балансировщик нагрузки), установку простого реле (возможно, qmail) на IP-адрес балансировщика нагрузки, настроенного так, чтобы разрешать только распознанные диапазоны в соответствии со стандартной практикой ретрансляции и с использованием простого циклического перебора DNS для записей MX для отправки входящего SMTP прямо на почтовые серверы. Но решение с балансировкой нагрузки было бы более элегантным.

Я использовал пользовательскую проверку tcp, поэтому

backend smtp-back
    mode tcp
    no option http-server-close
    balance roundrobin
    tcp-check expect string 220
    tcp-check send HELO\ test\r\n
    tcp-check expect string 250
    tcp-check send QUIT\r\n
    tcp-check expect string 221
    server mail01  mail01:25 check inter 60s rise 3 fall 3 backup
    server mail02  mail02:25 check inter 60s rise 3 fall 3 backup