Почтовый сервер и два IP-адреса (провайдера)
В данной заметке поговорим о том, как обеспечить бесперебойную работу почтового сервера в случае отказа одного из провайдеров интернет. Понятное дело, что если в вашей компании нестабильный интернет или вовсе аварии не редки, то в такой ситуации обычно подумывают о дополнительном интернет-канале, который в случае чего, возьмет на себя всю нагрузку. В данной статье мы не будет рассматривать конкретное оборудование и технологии для интернет-шлюза при помощи которого будет реализовано автоматическое переключение каналов, поскольку для каждой "железки" или сервера это довольно индивидуально. Предполагается что данная схема у нас уже реализована и осталось только открыть дополнительные порты на шлюзе, настроить 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 или выполнив команду:
postconf -e myhostname = mail2.mydomain.ru
И что бы изменения вступили в силу перезапустим службу.
service postfix restart
Но понятное дело, менять параметр вручную не совсем удобно, особенно если сбой произошел в нерабочее время, вечером или ночью, а почту при этом нужно принимать постоянно. Поэтому с целью оптимизировать данный процесс был написан простенький скрипт, который автоматически меняет параметр myhostname в файле /etc/postfix/main.cf в зависимости от текущего интернет соединения (wan1 или wan2). Скрипт в том виде в котором он представлен ниже, работает в реальной конторе и пока без сбоев.
#!/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
Обзовем данный скрипт например change_myhostname.sh и положим его в /var/vmail/backup. Для запуска его вручную выполняем:
shell change_myhostname.sh
Теперь сделаем его исполняемым при помощи команды:
chmod +x change_myhostname.sh
После чего фаил можно добавлять в планировщик cron и запускать следующим образом:
./change_myhostname.sh
Открываем на редактирование "рутовый" crontab
nano /etc/crontab
и вносим туда строку:
# Запускать скрипт каждые 10 мин. (или ваше время), а результат выполнения команды записывать в /var/log/cron.log. */10 * * * * root /var/vmail/backup/change_mail_host.sh >> /var/log/cron.log
Проверяем!