Сценарий, которого никто не ожидает
Вы только что завершили миграцию одного тенанта Google Workspace на другой. Поглощение компании, смена домена, слияние двух организаций, которые годами сосуществовали на отдельных аккаунтах G Suite. Всё прошло гладко: ящики на месте, пользователи заходят. Утром в понедельник первый тикет: «У всех писем одинаковая дата.» Потом второй. Потом десять.
Интуитивно кажется: наверное, что-то с IMAP, неправильно настроенный инструмент, какая-то экзотика. Но точно не миграция Google на Google. Тем не менее, именно здесь это и происходит.
Этот сценарий, пожалуй, хуже всего задокументирован в индустрии. Большинство IT-администраторов, столкнувшись с ним, тратят несколько часов на поиск причины на стороне почтового клиента, Outlook, настроек аккаунта - и только потом понимают, что проблема кроется в заголовках самих писем.
Почему миграция Google на Google ломает даты
Чтобы разобраться в происходящем, нужно вернуться к механике заголовков email. Каждое сообщение по стандарту RFC 2822 содержит поле Date:, которое проставляет клиент или сервер отправителя в момент отправки. Это «настоящая» дата письма - та, когда сообщение было написано и отправлено.
Но существует и другой механизм: INTERNALDATE в протоколе IMAP. Это серверная метаданная, указывающая, когда сообщение было помещено в ящик. И вот тут начинается самое интересное.
Когда инструмент миграции переносит письмо из одного тенанта Google Workspace в другой, он использует протокол IMAP (даже если оба сервера у Google). Сообщение считывается из источника, а затем вставляется в целевой ящик. В момент этой вставки сервер-получатель автоматически добавляет заголовок Received: с отметкой времени операции - то есть датой миграции.
При этом почтовые клиенты вроде Outlook используют первый Received: в цепочке для отображения даты сообщения, а не исходное поле Date:. Результат: все письма показывают дату дня миграции.
Какие инструменты вызывают проблему
Проблема затрагивает практически все инструменты, используемые для межтенантных миграций Google Workspace. Исключений нет:
- GSMMO (Google Workspace Migration for Microsoft Outlook): изначально предназначен для миграции с Exchange, но используется и в некоторых сценариях GWS на GWS.
- CloudM Migrate: очень распространён среди MSP для межгугловых миграций, всегда добавляет
Received:миграции. Подробнее в анализе CloudM. - BitTitan MigrationWiz: то же самое. Поведение разобрано в статье про BitTitan.
- imapsync: open-source инструмент для скриптовых миграций по IMAP, в том числе между двумя тенантами Google.
- Ручной экспорт/импорт через Takeout + повторный импорт по IMAP: встречается реже, но даёт ровно тот же эффект.
Причина проста: все эти инструменты работают как стандартные IMAP-клиенты. У них нет доступа к какому-то «нативному» пути Google, который сохранял бы метаданные. Даже если оба тенанта у Google, перенос идёт через IMAP-слой - а этот слой не знает, что «разговаривает сам с собой».
Механика заголовков Received в деталях
(Если Вы когда-нибудь пробовали читать сырые заголовки письма в Gmail или Outlook - Вы знаете, что это не самое увлекательное чтение. Но именно там прячется вся правда.)
Письмо, прошедшее обычный путь, содержит цепочку заголовков Received: в обратном порядке маршрута: последний сервер, коснувшийся сообщения, стоит первым. После миграции заголовок миграции оказывается в самом верху цепочки.
Вот как это выглядит в письме, перенесённом через CloudM из одного тенанта GWS в другой:
Received: from mail-migration.cloudm.io (mail-migration.cloudm.io [203.0.113.42])
by mx.google.com with ESMTPS id xyz123
for <user@new-domain.com>
; Mon, 14 Oct 2024 09:17:32 +0000 (UTC)
Received: from mail-relay.google.com ...
; Tue, 5 Mar 2019 14:22:08 +0000
Date: Tue, 5 Mar 2019 14:22:08 +0000
Поле Date: говорит 2019 год. Первый Received: говорит октябрь 2024-го. Outlook читает первый Received:. Пользователь видит октябрь 2024 для письма из 2019 года.
Исходное поле Date: нетронуто. Оно никуда не делось. Это хорошая новость: данные на месте, они просто ждут, когда их будут считывать правильно.
Outlook и Gmail ведут себя по-разному
Это важное уточнение. Пользователи, работающие через веб-интерфейс Gmail, как правило, видят правильные даты: Gmail в первую очередь использует поле Date: по RFC 2822 для отображения сообщений. На веб-стороне проблема менее заметна.
А вот пользователи, настроившие ящик Google Workspace в Outlook через IMAP (или через синхронизацию Exchange ActiveSync), получают неправильную дату в полной мере - потому что Outlook опирается на INTERNALDATE в IMAP, которое отражает дату первого Received:, добавленного при миграции.
Уточню: поведение Outlook зависит от версии и режима подключения. Outlook 2019 и Microsoft 365 (свежие версии) используют INTERNALDATE при подключении по IMAP. Более старые версии могут вести себя немного иначе. Но во всех случаях, наблюдавшихся на реальных production-окружениях, миграция GWS на GWS через IMAP даёт неправильные даты в Outlook.
В итоге в организациях, перешедших на новый тенант с гибридной схемой пользователей (одни на веб-Gmail, другие на Outlook), тикеты поступают непоследовательно. IT-команды тратят время на выяснение, «почему одни пострадали, а другие нет» - хотя ответ простой: всё зависит от почтового клиента.
Поглощения, слияния, смена домена: самые частые сценарии
Такие миграции отнюдь не редкость. Вот случаи, которые генерируют больше всего тикетов:
Поглощение компании
У поглощённой компании был собственный тенант Google Workspace (домен @staraya-kompaniya.ru). После сделки всё должно переехать на тенант материнской компании (@gruppa.ru). 250 ящиков, архивы, восемь лет истории переписки. BitTitan или CloudM заказывают для проведения операции. Результат: 2,4 миллиона писем с датой выходных, когда шла миграция.
Смена домена
Компания после ребрендинга переходит с @staroe-nazvanie.ru на @novoe-nazvanie.ru. Тот же тенант Google, но создаётся новый - чтобы начать с чистого листа (распространённый выбор, позволяющий избежать артефактов конфигурации). Ящики переносятся через imapsync или GSMMO. Даты ломаются ровно так же.
Консолидация дочерних компаний
Холдинг с четырьмя «дочками», каждая на своём историческом тенанте G Suite, решает свести всё под единый тенант. Четыре параллельные миграции - четыре партии писем с повреждёнными датами, которые нужно обработать.
Во всех трёх сценариях проблема одинакова, решение тоже. Чеклист миграции почты помогает предусмотреть подобные ситуации до запуска миграции.
Почему самописный скрипт - не выход
Понять проблему - это одно. Написать Python-скрипт, который «почистит заголовки», и применить его к 30 000 production-писем - совсем другое.
Граничных случаев масса. Скрипт, который отлично работает на 50 тестовых письмах в чистой среде, неизбежно столкнётся на реальном production-ящике с:
- Сообщениями с подписями S/MIME или контентом, зашифрованным PGP, - где любое изменение структуры письма инвалидирует криптографическую подпись.
- Письмами со сложными вложенными структурами MIME (multipart/alternative внутри multipart/mixed с вложениями по несколько десятков мегабайт).
- Заголовками, закодированными по RFC 2047 (не-ASCII символы), которые плохо настроенные парсеры съедают незаметно.
- Ошибками 429 Too Many Requests от Google API в два часа ночи, посреди пакетной обработки, - когда процесс зависает в неопределённом состоянии.
- Письмами, где цепочка
Received:неоднозначна: несколько последовательных инструментов миграции добавили каждый свой заголовок, и не так просто определить, какой именно удалять.
И главный вопрос: как проверить, письмо за письмом, что каждое исправленное сообщение осталось целым и ничего не потеряно и не повреждено? Самописный скрипт такую проверку обычно не делает. Redate.io делает её автоматически, сохраняя оригиналы в резервной папке, которая видна пользователю в течение 30 дней.
Что делает Redate.io с такими миграциями
Redate.io подключается к целевому тенанту Google Workspace (через делегирование на уровне домена, без ручной настройки каждого ящика) и сканирует письма, выявляя те, у которых метаданные даты не соответствуют содержимому сообщения. Фаза сканирования бесплатна и даёт точное представление о масштабе проблемы до любых исправлений.
Затем проприетарный движок коррекции анализирует цепочку заголовков каждого сообщения, применяет сопоставление паттернов по сигнатурам известных инструментов миграции (BitTitan, CloudM, imapsync, GSMMO и ряд более редких), и выполняет точечную коррекцию метаданных без изменения содержимого письма. Каждое исправленное письмо проверяется индивидуально. Оригиналы сохраняются.
Для межтенантных миграций Google Workspace конвейер обрабатывает и случаи многократной миграции (например, ящик перенесли сначала в 2021 году, потом снова в 2024-м), когда нужно распутать несколько слоёв лишних заголовков.
Руководства по конкретным сценариям - CloudM в Google Workspace и BitTitan в Google Workspace - описывают шаги подключения для такой конфигурации.
Обнаружить проблему до того, как пожалуются пользователи
Лучший момент для обнаружения повреждённых дат - сразу после миграции, до go-live. Быстрая проверка нескольких пилотных ящиков через IMAP-клиент вроде Thunderbird позволяет сравнить отображаемые даты с ожидаемыми. Если все перенесённые письма как будто имеют одну и ту же свежую дату - это характерный признак проблемы.
На практике, однако, проблему замечают часто уже через несколько недель после миграции - когда пользователь ищет старый договор и обнаруживает, что его ящик идеально отсортирован... по дате миграции. Тысячи писем с одинаковой отметкой времени. Поиск по дате не работает. Переписка в беспорядке. История переписки словно исчезла.
Для MSP, которые регулярно проводят межтенантные миграции Google Workspace, включить сканирование Redate.io в чеклист после миграции (до приёмки клиентом) - это способ избежать подобных неприятностей.
Вы только что выполнили миграцию между двумя тенантами Google Workspace и даты писем оказались неверными? Запустите бесплатное сканирование на Redate.io и оцените масштаб проблемы до начала исправлений.