Переезд Zimbra на новый IP и hostname: zmsetservername целиком

Стройке в Одинцове меняли провайдера, и вместе с ним менялся весь адресный план — включая почтовый сервер. Мы вышли в ночь на субботу с планом на два часа, а закончили в 07:20 субботы. Причина простая: старую запись в DNS убрали на двадцать минут раньше, чем следовало.

Когда провайдер меняется, а почта остаётся

Смена провайдера в небольшой компании выглядит безобидно. Приходят монтажники, тянут новый кабель, отдают блок адресов, старый канал держат ещё пару недель для верности. Сайт переезжает за час, VPN — за вечер. И где-то в конце списка стоит строчка «почтовый сервер», которую все считают такой же простой задачей.

Она не простая. Zimbra не хранит своё имя в одном месте. Оно вписано в конфигурацию каждой службы, в объект сервера в каталоге LDAP, в сертификат, в карту логгера, в записи домена. Пока имя резолвится в старый адрес, всё работает. Как только перестаёт — половина служб не поднимается, и разбираться приходится с каждой по отдельности.

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

Ниже — как это делается целиком, что именно пошло не так у меня и почему порядок шагов важнее самих шагов.

Август 2019, Одинцово: 37 рабочих мест и новый блок адресов

Строительная компания, офис и производственная база в Одинцове, 37 рабочих мест. Уходили от провайдера, который поднял тариф вдвое, к другому — с блоком из восьми адресов вместо одного. Меняли всё: внешний адрес, шлюз, внутреннюю адресацию за роутером тоже решили привести в порядок заодно.

Почтовый сервер на тот момент:

  • Zimbra 8.8.15 Open Source Edition, CentOS 7, физический сервер в серверной — до 8.8.15 их дотянули весной того же года, как раз перед историей с переездом;
  • однохостовая инсталляция — LDAP, MTA, mailstore и прокси на одной машине;
  • 37 ящиков, store 190 ГБ, самый большой ящик — 21 ГБ у главного инженера;
  • имя mail.old-domain.ru, оно же в сертификате Let's Encrypt.

Заказчик хотел заодно поменять и имя: почта переезжала на домен, который компания использовала как основной, — то есть менялся не только адрес, но и полное имя хоста. Это, кстати, ровно тот случай, когда работы нельзя разбить на два вечера: имя и адрес завязаны друг на друга, и половинчатое состояние хуже обоих крайних.

План был на 2 часа в ночь с пятницы на субботу. Технически он был правильный. Ошибка обнаружилась не в плане, а в том, кто и когда нажимает кнопки.

Готовиться начали за сутки. Первое, что сделали в четверг днём, — снизили TTL всех записей почтового домена с 3600 до 300 секунд. Это единственное действие подготовки, которое нельзя пропускать: с часовым TTL переключение растянется на полдня, и вы не поймёте, сломалось у вас что-то или просто кэш.

Полная процедура: порядок, который отработал

Последовательность ниже я с тех пор не менял. Она выглядит скучно, и в этом её достоинство.

Шаг 1. Зафиксировать, что есть сейчас. До любых правок снимаем текущее состояние — потом будет с чем сверять:

$ su - zimbra
$ zmhostname
mail.old-domain.ru
$ zmprov gs $(zmhostname) | grep -iE 'zimbraServiceHostname|zimbraServiceEnabled|zimbraMtaMyNetworks'
$ zmprov gd old-domain.ru | grep -iE 'zimbraDomainName|zimbraPublicServiceHostname'
$ zmlocalconfig -s zimbra_server_hostname ldap_master_url ldap_url

Шаг 2. Остановить Zimbra полностью. Не отдельные службы — всё:

$ zmcontrol stop
$ ps -u zimbra | wc -l

Вторая команда нужна, чтобы убедиться: процессов не осталось. Пустой вывод zmcontrol stop ещё ничего не гарантирует.

Шаг 3. Поменять имя на уровне операционной системы. Сначала /etc/hosts, потом /etc/hostname. В /etc/hosts новое имя обязано разрешаться в локальный адрес сервера, и никак иначе:

# /etc/hosts
192.168.30.10   mail.new-domain.ru mail
127.0.0.1       localhost localhost.localdomain

# /etc/hostname
mail.new-domain.ru

Шаг 4. Собственно смена имени внутри Zimbra:

# я запускаю от root, после чего обязательно проверяю владельцев файлов
/opt/zimbra/libexec/zmsetservername -n mail.new-domain.ru
ls -l /opt/zimbra/conf/localconfig.xml

Утилита проходит по объектам каталога и переписывает имя сервера везде, где оно встречается. Работает не мгновенно: у нас на 37 ящиках заняла около десяти минут.

Шаг 5. Почистить карту логгера. Она хранит соответствие «имя хоста — сервер» и остаётся со старым значением:

$ su - zimbra
$ zmloggerhostmap

Шаг 6. Ещё раз остановить и перезагрузить машину. Именно перезагрузить, а не перезапустить службы: имя хоста подхватывается на старте, и часть демонов иначе останется со старым.

Шаг 7. После загрузки — поднимать и смотреть в лог, а не в статус:

$ su - zimbra -c 'zmcontrol start'
$ tail -f /opt/zimbra/log/mailbox.log

Где мы легли: A-запись убрали на двадцать минут раньше

Ошибка вышла бытовая. Пока я занимался сервером, коллега на другом конце офиса переносил зону к новому регистратору. В списке дел у него стояло «убрать старые записи» — и он их убрал. В том числе A-запись mail.old-domain.ru. В этот момент zmsetservername у меня ещё крутился.

Через несколько минут после старта служб мы получили вот это:

Unable to contact ldap://mail.old-domain.ru:389: Invalid argument

Дальше я потратил час не туда. Логика была такая: раз не удаётся соединиться с LDAP по порту 389, значит новый провайдер что-то фильтрует или заработали новые правила на роутере. Полез в iptables, поднял tcpdump, проверил, что порт слушается локально. Всё было в порядке. Соединения просто не начинались.

Понял я это, когда сделал самую очевидную вещь, до которой почему-то дошёл не сразу:

$ dig +short mail.old-domain.ru
$ echo $?
0

Пустой ответ. Имя, на которое всё ещё ссылалась часть конфигурации, перестало существовать в природе. Порт был ни при чём — до порта дело не доходило, соединение падало на разрешении имени.

Механика здесь простая, и о неё бьются регулярно. zmsetservername не переписывает конфигурацию мгновенно и атомарно: пока он не закончил и пока службы не подтвердили новое имя, часть ссылок ведёт на старое. Если старое имя в этот момент не резолвится — процесс остаётся в наполовину переписанном состоянии, и LDAP-клиент внутри Zimbra уходит в ошибку.

Лечится в лоб: возвращаем A-запись на место и доводим процедуру до конца. Мы вернули её в 03:40, запись разошлась благодаря заранее сниженному TTL за пять минут, и дальше всё пошло по плану. Без сниженного TTL мы бы сидели до утра.

Проверьте у себя за две минуты

Эта проверка полезна не только перед переездом. Она показывает, согласовано ли у вас имя сервера прямо сейчас — а расхождение случается и само по себе, например после восстановления виртуалки из снимка или переустановки ОС «поверх».

$ hostname -f
$ su - zimbra -c 'zmhostname'
$ su - zimbra -c 'zmprov gs $(zmhostname) zimbraServiceHostname'
$ dig +short $(hostname -f)
$ dig +short -x $(hostname -I | awk '{print $1}')

Все пять строк должны говорить об одном и том же имени и одном адресе. Что означают расхождения:

Что увиделиЧто это значитНасколько срочно
hostname -f и zmhostname различаютсяИмя меняли в системе, но не внутри Zimbra. Часть служб работает на старомДо ближайшей перезагрузки — она вскроет проблему
dig по имени не отдаёт ничегоЗаписи нет либо она внутри, а сервер смотрит наружу. Классика после смены DNSСегодня
dig отдаёт адрес, которого нет на сервереИмя ведёт на старый или чужой хостСегодня
Обратная запись пустая или чужаяPTR не переехал вместе с адресом — почта пойдёт в спамВ первый же день после смены IP
TTL записей 3600 и выше, а переезд на этой неделеПереключение растянется на часы, диагностика станет невозможнойСнизить за сутки до работ
В /etc/hosts имени нет вовсеСервер зависит от внешнего DNS даже для самого себяДобавить до любых работ

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

Что доделывали после: сертификат, PTR и сети MTA

Службы поднялись в 04:15. Работа на этом не кончилась — сменилось имя, а вместе с ним стало неверным ещё несколько вещей.

Сертификат. Старый был выписан на mail.old-domain.ru. Браузеры и почтовые клиенты честно ругались. Выпустили новый и проверили цепочку до установки:

$ su - zimbra
$ /opt/zimbra/bin/zmcertmgr verifycrt comm /opt/zimbra/ssl/zimbra/commercial/commercial.key \
      /tmp/new/cert.pem /tmp/new/chain.pem
$ /opt/zimbra/bin/zmcertmgr deploycrt comm /tmp/new/cert.pem /tmp/new/chain.pem
$ zmcontrol restart

Сети MTA. Внутренняя адресация тоже поменялась, а в параметре доверенных сетей остались старые подсети. Симптом был бы отложенный и неприятный: часть внутренних систем перестала бы отправлять уведомления через сервер:

$ zmprov ms $(zmhostname) zimbraMtaMyNetworks '127.0.0.0/8 192.168.30.0/24'

Обратная запись. Новый провайдер прописал PTR на свой шаблон вида host-93-x-x-x.provider.ru. С таким PTR письма отправляются, но принимающие стороны относятся к ним настороженно. Заявку на нужную запись подали в пятницу утром, сделали её только во вторник — четверо суток почта уходила с чужим именем в обратной зоне. Это надо закладывать в план заранее, потому что от вас тут ничего не зависит.

MX и SPF. MX переключили последним, уже утром субботы, когда сервер устойчиво отвечал на новом адресе. В SPF добавили новый адрес, а старый оставили ещё на две недели — на время, пока старый канал был жив, и на всякий случай.

Ещё одна мелочь, стоившая нам двадцати минут: после перезагрузки службы не поднялись с первого раза, и zmcontrol ругнулся на нечисловой идентификатор процесса. В /opt/zimbra/log остались PID-файлы от аварийно завершённых демонов. Убрали, стартовали заново, поднялось.

Итоги ночи в цифрах и во что это встало

Хронология получилась такая:

ВремяЧто происходило
чт, 14:00TTL записей снижен с 3600 до 300 секунд
сб, 01:30zmcontrol stop, правка /etc/hosts и /etc/hostname
сб, 01:48Запущен zmsetservername
сб, 01:55Коллега удалил старую A-запись
сб, 02:10Первое Unable to contact ldap://mail.old-domain.ru:389
сб, 02:10–03:35Час двадцать я искал проблему в файрволе. Не там
сб, 03:40Запись возвращена в зону
сб, 04:15Все службы поднялись на новом имени
сб, 06:05Развёрнут новый сертификат, переключён MX
сб, 07:20Проверка приёма и отправки, работы закрыты

Пять часов пятьдесят минут вместо запланированных двух. Из них час двадцать — чистая потеря на ложном следе, ещё около часа — на то, что делалось бы всё равно, но не ночью.

Писем при этом не потеряли ни одного, и вот почему: MX всё это время указывал на старый адрес, который оставался живым. Отправители, которые не смогли достучаться, получали временную ошибку и повторяли попытку — это штатное поведение, письма не пропадают, а откладываются. Мы разгребли очередь утром: в отложенных лежало 173 письма, все доехали.

Цена вопроса, если бы мы пошли по короткому пути и сделали это в рабочий день. Тридцать семь человек без почты — а с учётом того, что стройка живёт заявками и согласованиями по почте, это остановка работы отдела снабжения и сметчиков. Считали грубо: 5 часов 50 минут × 37 человек ≈ 216 человеко-часов. При 500 рублях за час — 108 тысяч рублей упущенной работы, не считая сорванных сроков по двум тендерам с дедлайном в понедельник. Ночное окно обошлось им в 33 000 рублей: шесть часов по ночной ставке 5 500 рублей за час.

33 тысячи против 108 — больше чем втрое, и это без тендеров. Вот этот счёт на двух строчках — единственный аргумент, который в таких разговорах работает.

Что стоит унести из этой истории

Короткий список, который я теперь проговариваю с заказчиком до начала работ.

  • Старое имя живёт до последнего. Не удаляйте A-запись, пока службы на новом имени не отработали хотя бы час. Она вам ничего не стоит, а без неё вы застрянете.
  • TTL снижается за сутки. Не за час до работ — за сутки, иначе снижение само не успеет разойтись.
  • Кнопки нажимает один человек. Наша ошибка была не технической: два специалиста делали части одной задачи параллельно и по своим спискам.
  • Проверять надо в логе, а не в статусе. zmcontrol status в такие моменты — плохой советчик; смотрите mailbox.log, там причина написана словами.
  • PTR не зависит от вас. Заявку провайдеру подавайте одновременно с планированием работ, а не после.

И про совет, который часто дают в форумах: «проще поставить новый сервер и перенести на него ящики, чем менять имя старому». Для крупной инсталляции — возможно. Для тридцати семи ящиков это подмена одной ночной работы многодневной миграцией с переносом почты, паролей, календарей и общих папок. Мы посчитали оба варианта: смена имени — одна ночь, полный перенос — три ночных окна и неделя разбора хвостов. Прыгать в миграцию имеет смысл, когда есть вторая причина: старая версия, мёртвая ОС под сервером, железо на грани.

Собираетесь менять провайдера или адресацию и не уверены, что почта переживёт? Выполните пять команд из раздела «Проверьте у себя за две минуты» и пришлите вывод — я за день скажу, согласовано ли у вас имя сейчас, что придётся править и уложится ли переезд в одно ночное окно. Если увижу, что нужен не переезд имени, а что-то другое, напишу прямо.

Частые вопросы

Можно ли поменять только IP, не трогая hostname?

Можно, и это заметно проще. Тогда достаточно поправить адрес в /etc/hosts, обновить A-запись и доверенные сети MTA через zmprov ms $(zmhostname) zimbraMtaMyNetworks, а также заказать у провайдера обратную запись на новый адрес. zmsetservername в этом случае не нужен вовсе — имя не меняется, а вся конфигурация Zimbra завязана именно на имя, а не на адрес. Одна оговорка: если у вас в конфигурации где-то прописан голый IP вместо имени, найдите эти места заранее, иначе они всплывут через неделю в самый неудобный момент.

Сколько по времени работает zmsetservername?

На однохостовой инсталляции с 37 ящиками у меня заняло около десяти минут. Время зависит не от объёма почты, а от количества объектов в каталоге — доменов, учётных записей, списков рассылки, классов обслуживания. На двух-трёх сотнях ящиков закладывайте 10–15 минут. Главное правило: не прерывать. Если процесс остановить на середине, конфигурация останется наполовину переписанной, и разбирать её потом придётся руками через zmprov, сверяя объекты по одному. Запускайте в screen или tmux, чтобы обрыв сессии ничего не сломал.

После смены имени служба не стартует и ругается на нечисловой идентификатор процесса. Что это?

Это осиротевшие PID-файлы в /opt/zimbra/log, оставшиеся от процессов, которые завершились нештатно — например, при перезагрузке в середине процедуры. Скрипт управления читает файл, находит там мусор вместо номера и падает. Порядок действий: убедиться командой ps -u zimbra, что живых процессов действительно нет, удалить файлы *.pid и стартовать заново. Если процессы есть — сначала завершить их, иначе получите два экземпляра одной службы. И запускайте управление строго из-под пользователя zimbra, а не от root.

Потеряются ли письма, пока сервер недоступен?

Нет, если вы не трогали MX раньше времени. Отправляющий сервер, не сумев доставить письмо, получает временную ошибку и складывает письмо в свою очередь, повторяя попытки несколько суток. У нас за ночь накопилось 173 отложенных письма, и все они доехали в течение получаса после того, как сервер поднялся. Опасны здесь два сценария: MX переключили на адрес, который ещё не принимает почту, — тогда письма будут отбиваться постоянной ошибкой; либо работы затянулись дольше срока жизни очереди у отправителей. Поэтому MX я переключаю последним действием, а не первым.

Обязательно ли ночное окно, или можно сделать это днём за пару часов?

Технически — можно, процедура одинаковая. Экономически — считайте сами. У клиента в Одинцове работы заняли пять часов пятьдесят минут против плановых двух, и это при подготовке и снятом заранее TTL. Днём это означало бы 37 человек без почты на большую часть рабочего дня, около 216 человеко-часов и два тендера с дедлайном в понедельник под угрозой. Даже идеально прошедшая процедура требует перезагрузки сервера и повторного старта служб — это минимум двадцать минут полного простоя, которые невозможно сократить.

Нужна помощь с проектом?

Специалисты АйТи Фреш помогут с архитектурой, DevOps, безопасностью и разработкой — 15+ лет опыта

📞 Связаться с нами
#Zimbra#hostname#LDAP#DNS#миграция
Комментарии 0

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

загрузка...

Подпишитесь на рассылку ITfresh

Раз в неделю — практические гайды для руководителя IT и сисадмина: безопасность, 1С, миграции, резервные копии, лайфхаки из реальных проектов.

Реквизиты оператора персональных данных

ООО «АЙТИ-ФРЕШ», ИНН 7719418495, КПП 771901001. Юридический адрес: 105523, г. Москва, Щёлковское шоссе, д. 92, корп. 7. Контакт: info@itfresh.ru, +7 903 729-62-41. Оператор обрабатывает e-mail подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.