HP260-g1-win32_winsat_4gb

Данная заметка о том, как обеспечить бесперебойную работу почтового сервера в случае отказа одного из провайдеров интернет. Понятное дело, что если в вашей компании нестабильный интернет или вовсе аварии не редки, то в такой ситуации обычно подумывают о дополнительном интернет-канале, который в случае чего, возьмет на себя всю нагрузку. В данной статье мы не будет рассматривать конкретное оборудование и технологии для интернет-шлюза при помощи которого будет реализовано автоматическое переключение каналов, поскольку для каждой «железки» или сервера это довольно индивидуально. Предполагается что данная схема у нас уже реализована и осталось только открыть дополнительные порты на шлюзе, настроить DNS и почтовый сервер в случае работы через второго провайдера. Поехали!

Исходные данные следующие:

IP-адрес первого провайдера, wan1 — 11.22.33.44;

IP-адрес второго провайдера, wan2 — 22.33.44.55;

Почтовый сервер на базе Linux (postfix) располагается за NAT в локальной сети. Сетевое имя (/etc/hostname) —  mail. В /etc/hosts дополнительно прописано FQDN-имя сервера указывающее на аналогичную MX-запись на DNS-сервере регистратора доменных имен — mail.mydomain.ru

В главном конфигурационном файле postfix (/etc/postfix/main.cf) директиве myhostname так же отвечающей за полное доменное имя машины (FQDN), назначен параметр mail.mydomain.ru, который мы и будем менять в зависимости от доступности того или иного wan-интерфейса.

myhostname = mail.mydomain.ru

Но об этом чуть ниже.

В обычном случае для работы любой почтовой cистемы, по одному каналу, в ресурсных записях DNS на сервере регистраторе доменных имен должно быть прописано следующее:

доменное имя: mydomain.ru
mail A 11.22.33.44
@ MX 0 mail

где, первая строка (А-запись) говорит нам о том, что mail.mydomain.ru указывает на IP-адрес 11.22.33.44, соответствующий нашему основному провайдеру (wan1), вторая строчка (MX-запись) указывает на то что данный домен mail.mydomain.ru является адресом почтового шлюза. Цифра указывает на приоритет, а последующая запись на имя сервера, которое будет до основной доменной части. В нашем случае «mail». Благодаря MX-записи отправляющая сторона «понимает» на какой сервер нужно отправлять почту для нашего домена.

Теперь что бы позволить нашей почтовой системе работать через второго провайдера, ресурсные записи DNS приводим к следующему виду:

доменное имя: mydomain.ru
mail A 11.22.33.44
mail2 A 22.33.44.55
@ MX 0 mail
@ MX 1 mail2

где, «mail2 A 22.33.44.55» говорит нам о том, что добавлен узел mail2.mydomain.ru указывающий на IP-адрес 22.33.44.55, соответствующий второму (резервному) провайдеру — wan2, а запись «@ MX 1 mail2» — говорит о том что, если основной почтовый сервер mail.mydomain.ru недоступен и не принимает соединения на 25 порту, то необходимо начинать принимать соединения по второму адресу mail2.mydomain.ru с более низким приоритетом, в данном случае «1»

На интернет-шлюзе у нас должен быть открыт 25 порт c основного и резервного wan-интерфейсов на внутренний 25 порт почтового сервера mail.

Не забываем так же, попросить ваших провайдеров интернет добавить PTR-записи для основного и дополнительного адреса соответственно, иначе обеспечить 100% корректную доставку писем до нашего сервера не получится.

Если у вас используется SPF-запись снижающая вероятность попадания писем от вашего сервера в спам, то не забываем прописать туда IP резервного провайдера, например у меня запись выглядит следующим образом:

@ TXT v=spf1 +a +mx ip4:11.22.33.44 ip4:22.33.44.55 -all

Теперь если основной канал откажет, то основным почтовым шлюзом станет mail2.mydomain.ru и трафик пойдет через второго провайдера, а для того что бы точно гарантировать доставку писем до нашего локального сервера, необходимо изменить параметр myhostname на mail2.mydomain.ru.

myhostname = mail2.mydomain.ru

Сделать это можно вручную, редактированием /etc/postfix/main.cf или выполнив команду:

[bash]postconf -e myhostname = mail2.mydomain.ru[/bash]
И что бы изменения вступили в силу перезапустим службу.
[bash]service postfix restart[/bash]

Но понятное дело, менять параметр вручную не совсем удобно, особенно если сбой произошел в нерабочее время, вечером или ночью, а почту при этом нужно принимать постоянно. Поэтому с целью оптимизировать данный процесс был написан простенький скрипт, который автоматически меняет параметр myhostname в файле /etc/postfix/main.cf в зависимости от текущего интернет соединения (wan1 или wan2). Скрипт в том виде в котором он представлен ниже, работает в реальной конторе и пока без сбоев.

[bash]#!/bin/sh
# Задаем переменные, ip1 и ip2 — каналы интернет указывающие на wan1 и wan2 соответственно;
ip1=11.22.33.44
ip2=22.33.44.55

# Задаем переменные, string1 и string2 — строки указывающие на возможный параметр «myhostname» в /etc/postfix/main.cf;
string1=»myhostname = mail.mydomain.ru»
string2=»myhostname = mail2.mydomain.ru»

# Смотрим текущее значение параметра «myhostname» и результат присваиваем переменной $get_string;
get_string=$(sed -n 30p /etc/postfix/main.cf)

# Определяем текущий внешний IP-адрес и результат присваиваем переменной $current;
current=$(wget -O — -q icanhazip.com)

# Задаем функцию получения текущего времени;
now_time() {
date +»%Y-%m-%d %H:%M:%S»
}
# Перебор разных условий определяющих соответствие текущего IP-адреса и параметра myhostname. В зависимости от результата
# вносятся изменения в main.cf, перезапускается postfix и выводится информация при помощи echo,
# которая затем пишется в log-фаил при помощи cron.
if [ «$current» = «$ip1» ] && [ «$get_string» = «$string1» ]; then
echo «`now_time` Текущий ip = $ip1, а значение строки $string1, поэтому оставляем как есть!»
elif [ «$current» = «$ip2» ] && [ «$get_string» = «$string2» ]; then
echo «`now_time` Текущий ip = $ip2, а значение строки $string2, поэтому оставляем как есть!»
elif [ «$current» = «$ip2» ] && [ «$get_string» = «$string1» ]; then
echo «`now_time` Текущий ip = $ip2, а значение строки $string1, поэтому меняем значение параметра на $string2»
postconf -e myhostname=mail2.mydomain.ru
service postfix restart

# В случае переключения на резервный канал отправить почтовое сообщение (текст после echo) от почтового ящика admin@mydomain.ru на sanotes@yandex.ru;
echo «Переключение на резервный канал, изменение параметра myhostname на mail2.mydomain.ru» | mail -s «mail server» sanotes@yandex.ru -aFrom:admin@mydomain.ru

# Перебор разных условий (см. выше)
elif [ «$current» = «$ip1» ] && [ «$get_string» = «$string2» ]; then
echo «`now_time` Текущий ip адрес $ip1, а в строке стоит mail2, поэтому меняем значение параметра на $string1»
postconf -e myhostname=mail.mydomain.ru
service postfix restart

# В случае переключения на основной канал отправить почтовое сообщение (текст после echo) от почтового ящика admin@mydomain.ru на sanotes@yandex.ru;
echo «Переключение на основной канал, изменение параметра myhostname на mail.mydomain.ru» | mail -s «mail server» sanotes@yandex.ru -aFrom:admin@mydomain.ru
fi
[/bash]
Обзовем данный скрипт например change_myhostname.sh и положим его  в /var/vmail/backup. Для запуска его вручную выполняем:
[bash]bash change_myhostname.sh[/bash]
Теперь сделаем его исполняемым при помощи команды:
[bash]chmod +x change_myhostname.sh[/bash]
После чего фаил можно добавлять в планировщик cron и запускать следующим образом:
[bash]./change_myhostname.sh[/bash]
Открываем на редактирование «рутовый» crontab
[bash]nano /etc/crontab[/bash]
и вносим туда строку:
[bash]# Запускать скрипт каждые 10 мин. (или ваше время), а результат выполнения команды записывать в /var/log/cron.log.
*/10  *   *   *   * root /var/vmail/backup/change_mail_host.sh >> /var/log/cron.log
[/bash]
Проверяем!

10 КОММЕНТАРИИ

    • Nikita, у меня в статье одно из решений, думаю можно реализовать по разному и даже проще чем у меня и обойтись совсем без скриптов. Не понял что дадут две одинаковые ptr-записи, кроме того что будут помогать корректно проходить проверки на наличие ptr-записей у тех серверов которые это проверяют!? Такая запись желательна, но в настоящий момент такие проверки редко у кого стоят и поэтому это не сильно актуально. У меня например на резервном, мобильном провайдере предоставляющем внешний ip-адрес ptr-запись вообще не прописана, по причине того что провайдер не хочет или не может этого сделать, не разбирался еще, но почта тем не менее по второму ip и соответственно домену приходит. Это скорее надо создать две одинаковые A-записи указывающие на разные ip, а MX оставить одной, а прописывать в принципе ptr или нет это уже второе дело.

  1. а как быть со своими сотрудниками, которые соединяются с сервером из внешней сетки? У них почтовые клиенты настроены на mail.mydomain.ru сервер, а он не доступен.

    • Алекcей, тогда второй вариант который у меня сейчас реализован, в процессе тестирования так сказать, но пока не добавлен в статью. В днс, оставляем одну MX-запись указывающую на субдомен mail и создаем две одинаковые A-записи с именем mail, но указывающие на разные ip. Основной и резервный соответственно.
      т.е. должно быть:

      @ MX 0 mail
      mail A 11.22.33.44
      mail A 22.33.44.55
      

      и незабываем про ptr-записи:

      44.33.22.11.in-addr.arpa name = mail.mydomain.ru
      55.44.33.22.in-addr.arpa name = mail.mydomain.ru
      

      В этом случае, даже со скриптами заморачиваться не надо, если первый в списке ip не доступен, трафик идет по второму.

  2. А на сколько бедт задерживаться почта в случае конфигурации:

    @ MX 0 mail
    mail A 11.22.33.44
    mail A 22.33.44.55

    Все-таки чужой почтовый сервер будет пытаться отправить почту по одному из ип адресов, однако он может быть в этот момент не доступен.

    • ИгорьК, сложно сказать. По идее зависит от настроек сервера отправителя, но на практике я пока не заметил каких-то особых проблем с недоставкой писем в случае переключения на резервный канал.

  3. В записи SPF, нет нужды прописывать ip серверов в явном виде, параметр +mx означает что отправлять письма от имени вашего домена могут сервера указанные в MX записях DNS.

Оставьте комментарий

Войти с помощью: 
Please enter your comment!
Please enter your name here