Письма с неправильными датами после миграции cPanel

7 min

Понедельник утром, который всё портит

Вы только что завершили миграцию с общего хостинга cPanel на Google Workspace или Microsoft 365. Всё прошло нормально: ящики доступны, пользователи подключаются. Потом, около 9:15, приходит первый тикет: «Все старые письма показывают одну и ту же дату - прошлые выходные». Потом второй. Потом десять.

Это не единичный баг. Это прямое следствие того, как миграции с cPanel обрабатывают (точнее, не обрабатывают) метаданные дат писем.

cPanel, Roundcube, Horde: особый контекст IMAP

Общий хостинг cPanel - это Linux-сервер с IMAP-сервером (как правило, Dovecot) и Roundcube или Horde в качестве веб-интерфейса. Ничего экзотического. Но у этого контекста есть особенности, которые делают миграцию на корпоративные платформы сложнее, чем кажется.

Во-первых, почтовые ящики cPanel часто накапливают письма за годы, иногда за десятилетие. Клиент, который держал домен на shared-хостинге с 2013 года, может иметь очень глубокие архивы. Такой объём в сочетании с тем, как выполняется миграция, создаёт почву для проблем с датами.

Во-вторых, для таких миграций обычно используют либо встроенный инструмент cPanel (раздел «Migrations» в WHM), либо imapsync, запускаемый из командной строки хостером или IT-подрядчиком, либо потребительские решения вроде GSMMO для перехода на Google Workspace.

Почему даты нарушаются после миграции cPanel

Чтобы разобраться в проблеме, нужно понять два разных понятия: заголовок Date: письма и INTERNALDATE в IMAP.

Заголовок Date: записывается в тело сырого сообщения в момент отправки согласно RFC 2822. Он показывает, когда письмо было составлено и отправлено. Этот заголовок никогда не меняется, если только кто-то намеренно не модифицирует сообщение.

INTERNALDATE - это метаданные, которые IMAP-сервер связывает с каждым хранимым сообщением. Они отделены от содержимого письма. Когда письмо приходит на сервер в штатном режиме, INTERNALDATE определяется из заголовков Received: сообщения или по времени доставки. Именно это значение Outlook, Thunderbird и большинство почтовых клиентов используют для сортировки писем.

При IMAP-миграции письма копируются с одного сервера на другой. Проблема в том, что инструмент миграции должен заново создать каждое сообщение на сервере-назначении. И у многих инструментов INTERNALDATE нового сообщения соответствует дате миграции, а не исходной дате письма. Параллельно в начало цепочки заголовков добавляется заголовок Received: с отметкой времени миграции, что ещё больше запутывает почтовые клиенты, которые обращаются к нему для вычисления отображаемой даты.

Итог: письмо 2019 года попадает в Google Workspace с INTERNALDATE, установленным на день миграции, и заголовком Received:, датированным вчерашним числом. Outlook показывает его во входящих как будто оно только что пришло. Вся хронология архива уничтожена.

Инструмент миграции WHM / cPanel

Встроенный в WHM инструмент для миграции аккаунтов cPanel на другую платформу воспроизводит эту проблему почти систематически, когда целевой сервер - внешний IMAP (Google Workspace, Microsoft 365). Он копирует содержимое Maildir на новый сервер через IMAP APPEND без сохранения исходного INTERNALDATE. Каждое сообщение получает отметку времени момента операции.

imapsync и ручные миграции с cPanel

imapsync - мощный инструмент, но его поведение по умолчанию не всегда сохраняет даты. Без правильных параметров (и нужной версии) он вполне может скопировать 40 000 писем, присвоив им всем дату выполнения скрипта. (Кстати, если вы когда-нибудь перебирали логи imapsync строчку за строчкой, чтобы диагностировать проблему дат в ящике на 25 000 писем, вы знаете, что это не то развлечение, которое хочется повторять.)

Если быть точным: у imapsync есть опции для попытки сохранить дату, но эти опции по-разному взаимодействуют с разными серверами источника и назначения, и их эффективность не гарантирована для всех конфигураций cPanel / Dovecot.

GSMMO и потребительские инструменты

Google Workspace Migration for Microsoft Outlook (GSMMO) разработан для миграции из Outlook, а не с голого IMAP-сервера. Когда его используют для миграции с cPanel (через IMAP-аккаунт, настроенный в Outlook), даты проходят через то же самое: INTERNALDATE в Google Workspace фиксируется на дате миграции. Проблема GSMMO с датами писем задокументирована отдельно, настолько она распространена.

Какие почтовые клиенты затронуты?

Нарушение дат проявляется по-разному в зависимости от используемого клиента.

Outlook страдает больше всего. Он использует INTERNALDATE (или заголовок Received: миграции) как основной критерий сортировки в папках. После плохо выполненной миграции с cPanel ящик в Outlook может показывать тысячи архивных писем с датой выходных миграции. Исправление дат imapsync в Outlook - одно из самых востребованных исправлений.

Gmail (Google Workspace) обычно показывает дату из заголовка Date: в списке писем, но сортировка всё равно может нарушаться из-за INTERNALDATE в некоторых случаях. Пользователи сообщают об аномальном поведении поиска и сортировки по дате.

Apple Mail и Thunderbird ведут себя несколько иначе, но ни один из них не застрахован от проблемы - особенно когда заголовок Received: миграции стоит первым в цепочке.

Хорошая новость: исходная дата всегда на месте

Вот техническая деталь, которая меняет всё. Исходный заголовок Date: записан в теле сырого письма. Миграция его не трогает. Если открыть затронутое письмо и посмотреть на сырые заголовки (в Gmail: «Показать оригинал», в Outlook: Файл > Свойства), видно исходный Date: нетронутым, а за ним - один или несколько заголовков Received:, первый из которых несёт дату миграции.

Эта информация всегда присутствует. Её можно использовать для исправления метаданных. Именно это и делает движок коррекции Redate.io.

Почему «исправить самостоятельно» рискованнее, чем кажется

Соблазн велик. Задача кажется простой: прочитать исходную дату, исправить метаданные, перейти к следующему письму. Но между пониманием механизма и исправлением 12 000 писем на продуктивном сервере без единой потери - огромная пропасть.

Вот несколько реалий, которые самодельные скрипты обычно не учитывают:

  • Письма с S/MIME-подписью или PGP-шифрованием: любое изменение структуры сообщения аннулирует криптографическую подпись. Письмо, которое проходило проверку подписи до исправления, перестаёт проходить после. Пользователи из регулируемых отраслей (юридические фирмы, финансовый сектор, здравоохранение) обнаруживают это в самый неподходящий момент.
  • Не-ASCII заголовки и кодировка RFC 2047: ящики cPanel накапливают годы писем от самых разных почтовых клиентов. Некоторые заголовки содержат символы, закодированные по RFC 2047. Плохо написанный скрипт, который пересобирает заголовки, может незаметно испортить эти кодировки.
  • Вложенные MIME-структуры: письмо с тремя вложениями и альтернативным HTML-телом имеет сложную multipart-структуру. Малейшая ошибка на границах MIME делает сообщение нечитаемым, или хуже - вложения исчезают без сообщения об ошибке.
  • Квоты API и rate limiting: Google Workspace и Microsoft 365 устанавливают жёсткие лимиты на количество IMAP-операций в минуту. Скрипт без правильной реализации экспоненциального backoff вызывает ошибки 429 в три ночи, и вы просыпаетесь с наполовину выполненной миграцией - не зная, где именно она остановилась.
  • Откат невозможен: если что-то пошло не так на середине пути - к какому состоянию вы возвращаетесь? Оригиналы ещё целы? Есть ли дубликаты? Redate.io хранит оригиналы в видимой резервной папке в течение 30 дней именно для того, чтобы никогда не оказаться в такой ситуации.

Скрипт, который работает на 50 тестовых письмах в dev-окружении, не обязательно справится с 18 000 сообщений в production-ящике, переехавшем с cPanel-хостинга ещё в 2011 году.

Как Redate.io исправляет даты после миграции cPanel

Redate.io подключается напрямую к целевому ящику (Google Workspace через делегирование домена, Microsoft 365 через Azure AD или напрямую по IMAP) и начинает с бесплатного сканирования для выявления писем, у которых метаданные дат не соответствуют исходному заголовку Date:.

Затем многоступенчатый pipeline анализа применяет сопоставление паттернов по сигнатурам заголовков Received:, чтобы определить, какие из них добавлены инструментами миграции (и отличить их от легитимных). Целевая коррекция метаданных выполняется без изменения содержимого сообщения: текст, вложения, исходные заголовки - всё остаётся нетронутым. Каждое исправленное письмо проверяется индивидуально перед подтверждением операции.

Для миграций с cPanel движок распознаёт типичные сигнатуры миграций Dovecot-to-IMAP и скриптов imapsync, включая распространённые варианты конфигурации у российских и европейских shared-хостеров.

Руководства по конкретным платформам назначения

В зависимости от целевой платформы Вашей миграции с cPanel, следующие руководства описывают точные шаги:

Вы мигрировали с cPanel и Ваши пользователи видят неправильные даты? Запустите бесплатное сканирование на Redate.io, чтобы точно узнать, сколько писем затронуто, - без каких-либо изменений до Вашего подтверждения.

Похожие статьи