На следующее утро после восстановления начинаются обращения
Вы только что завершили восстановление почтового ящика через Veeam Backup for Microsoft 365. Операция прошла без сбоев, данные на месте, папки целы. И тут в понедельник утром пользователь пишет: «Все мои письма датированы сегодняшним числом. Я ничего не могу найти.»
Проблема не в том, что письма исчезли. Они на месте. Но отображаемая дата соответствует точному времени восстановления, а не дате отправки или получения. Письмо из января 2021 года выглядит как полученное вчера в 23:47. Цепочка переписки сломана. Хронология нечитаема.
Это поведение встречается в Veeam Backup for Microsoft 365, Datto SaaS Protection, Synology Active Backup for Microsoft 365 и AvePoint Cloud Backup, среди прочих. Каждый инструмент делает это по-своему, но результат одинаковый.
Что происходит на техническом уровне
Чтобы понять, откуда берётся неверная дата, нужно посмотреть, как эти инструменты повторно вставляют письма в Exchange Online или Google Workspace.
Когда инструмент резервного копирования восстанавливает сообщение, он не может просто «вернуть» письмо на место, как перенести файл на локальном диске. Он записывает новую копию сообщения в почтовый ящик через IMAP или через API провайдера: EWS или Microsoft Graph на стороне Microsoft, API Gmail на стороне Google. И вместе с этой копией он должен сообщить ящику, какую дату несёт письмо.
Вот тут и начинается проблема. (Кстати, если вы когда-нибудь смотрели на сырые заголовки восстановленного письма, то наверняка видели с десяток строк Received: прежде, чем добраться до полезного содержимого.)
Команда IMAP APPEND и заголовок Received:
В протоколе IMAP есть команда APPEND. Она используется для вставки сообщения в почтовый ящик. Именно это и делает инструмент восстановления: берёт сохранённое сообщение и вставляет его в целевой ящик через IMAP APPEND.
Эта команда позволяет инструменту передать дату вместе с письмом. Если инструмент передаёт исходную дату письма, ящик сохраняет её - это верно для Microsoft 365, Outlook.com и Gmail. Если же он не передаёт ничего или передаёт дату восстановления, письмо попадает в ящик под датой восстановления. А некоторые способы записи письма добавляют ещё одну строку сверху: заголовок Received:, датированный днём копирования. API импорта Gmail делает именно это.
Эта дополнительная строка выглядит примерно так:
Received: by gmailapi.google.com
with HTTPREST; Mon, 14 Apr 2025 23:47:12 +0000
Итог: оригинальное письмо внутри нетронуто, со своим исходным заголовком Date: (допустим, «3 Jan 2021 09:15:00»). Но поверх него добавлен новый заголовок Received: с датой восстановления.
Как Outlook и Gmail читают дату
Почтовые клиенты, такие как Outlook или веб-интерфейс Gmail, не всегда читают заголовок Date: для отображения даты в списке сообщений. Многие используют INTERNALDATE протокола IMAP, то есть дату добавления сообщения в ящик, или самый свежий заголовок Received:.
Outlook для Windows, особенно после обновления конца 2023 года, особенно чувствителен к этому. Увидев свежий заголовок Received: в начале цепочки, он использует его как дату отображения. Исходный Date: оказывается погребён в деталях сообщения и виден только при открытии свойств письма.
В результате пользователь видит список сообщений, все с датой ночи восстановления. Для него трёхлетняя история переписки только что сжалась в одну ночь.
Чем это отличается от проблемы миграции
Здесь важно отделить это от классической проблемы неверных дат после миграции IMAP. При миграции инструмент переносит письма с сервера A на сервер B, и сохранит ли письмо свою дату, зависит от того, что инструмент передаёт серверу B при записи. Механизм тот же, но контекст другой.
Здесь речь о восстановлении из резервной копии. Письма никуда не уходили из организации, их просто сохранили где-то (Azure Blob Storage, AWS S3, устройство Datto...) и затем вернули обратно. Пользователь ожидает этого меньше всего: для него возвращаются «его» письма, а не какие-то импортированные.
Но технически механизм тот же. Повторная вставка, которая не передаёт исходную дату, создаёт одинаковые артефакты. И исправление следует той же логике.
Как каждый инструмент работает с INTERNALDATE
Все инструменты ведут себя немного по-разному, и именно здесь всё становится интересным.
Veeam Backup for Microsoft 365
Veeam использует API EWS (Exchange Web Services) для восстановления в Exchange Online. EWS позволяет задать дату сообщения через поле DateTimeReceived, но это значение не всегда отражается на INTERNALDATE на уровне IMAP. Итог: дата сортировки в Outlook может не совпадать с оригинальной датой, особенно при гранулярном восстановлении в альтернативный ящик.
Datto SaaS Protection
Datto восстанавливает через Microsoft Graph API или IMAP в зависимости от конфигурации. В обоих случаях дата, которую показывает ящик, зависит от того, передаёт ли восстановление исходную дату каждого письма. MSP, использующие Datto для своих клиентов, сталкиваются с этой проблемой довольно регулярно, особенно после инцидентов с программами-вымогателями, когда срочно восстанавливают несколько сотен ящиков одновременно. Не лучший момент обнаружить, что все даты неверны.
AvePoint и Synology Active Backup
AvePoint Cloud Backup и Synology Active Backup for Microsoft 365 работают по схожим механизмам. AvePoint задокументировал это поведение в своей базе знаний (сообщение восстанавливается с датой восстановления как видимой датой получения), однако нативного исправления так и не предложил. Synology Active Backup имеет ту же проблему, усугублённую тем, что интерфейс восстановления не делает чёткого различия между «датой сообщения» и «датой восстановления».
Хорошая новость: исходная дата никуда не делась
Ситуацию спасает то, что исходный заголовок Date: сообщения не был изменён. Он по-прежнему присутствует, нетронутый, в каждом восстановленном письме. Восстановление изменило дату, которую видит ящик, а иногда добавляло сверху строку Received:, но не тронуло содержимое самого сообщения.
Это свойство формата MIME (RFC 2822): сообщение неизменно в своей внутренней структуре. Заголовки Received: накапливаются сверху как слои, но исходная информация остаётся под ними.
Так что нет, информация не потеряна. Она просто скрыта артефактом повторной вставки.
Почему повторное восстановление не решит проблему
Первая мысль: удалить восстановленные письма и запустить восстановление заново, надеясь, что на этот раз даты будут правильными. Это плохая идея по нескольким причинам.
Инструменты восстановления не будут вести себя иначе при повторном запуске. Один и тот же инструмент с теми же настройками запишет письма обратно так же, без их исходной даты. Вы получите ровно тот же результат.
Кроме того, повторное восстановление рабочих ящиков требует времени, трафика и несёт риски. На 50 ящиках с 20 000 сообщений каждый это операция на несколько часов, которая нагружает API и может вызвать ограничения на стороне Microsoft или Google (тот самый 429 Too Many Requests в два часа ночи во время пакетной обработки).
Вот в чём дело. Восстановление сработало. Данные на месте. Исправлять нужно артефакт даты, а не само восстановление.
Исправление своими силами: конкретные риски
Понять проблему - одно. Исправить её на 80 000 писем, не потеряв ни одного - совсем другое.
Python-скрипт, который обходит IMAP-сообщения и правит даты, может казаться реализуемым. На 50 тестовых письмах он отработает отлично. В продакшене всё иначе. Краевые случаи накапливаются: письма с подписью S/MIME (изменение заголовка аннулирует криптографическую подпись), PGP-зашифрованные сообщения, многочастные структуры с нестандартными MIME-границами, заголовки в кодировке RFC 2047 (не-ASCII), вложения на 40 МБ, которые взрывают память скрипта. И письма с несколькими добавленными заголовками Received: (если восстановление частично перезапускалось, что бывает), требующими более тонкой логики обнаружения.
Если быть точным, настоящий риск - не скрипт, который падает с ошибкой. Это скрипт, который работает без видимых ошибок, но создаёт искажённые сообщения. Сломанные цепочки обсуждений. Дубликаты. Отсоединённые вложения. Которые вы обнаружите, может быть, через несколько недель, когда пользователь попытается найти важное письмо.
И как вы проверите, что каждое исправленное письмо действительно целое после изменения? Самодельный скрипт этого, как правило, не делает.
Что Redate.io делает иначе
Redate.io анализирует цепочку заголовков каждого письма, чтобы выявить артефакты повторной вставки, будь то восстановление через Veeam, миграция BitTitan или ручной импорт. Проприетарному движку коррекции не нужно знать, какой инструмент виноват: он ищет письма, чья отображаемая дата не совпадает с оригинальной, и поэтому обнаруживает даже инструмент, о котором никто не слышал.
Прежде чем что-либо исправлять, Redate.io сканирует весь ящик и предоставляет отчёт: сколько писем затронуто, какая дата неверна, какая исходная дата обнаружена. Это сканирование бесплатно. Вы видите масштаб проблемы до принятия решения.
Каждое письмо проверяется индивидуально после коррекции. Оригиналы хранятся в видимой резервной папке до тех пор, пока вы сами их не удалите, что обеспечивает полную страховку в случае необходимости.
Redate.io открывает почтовый ящик после того, как пользователь входит через свою учётную запись, без портала и регистрации приложения, и письма не проходят через промежуточные серверы. Коррекция выполняется на месте, прямо в ящике, без экспорта и реимпорта.
MSP, одновременно обслуживающим нескольких затронутых клиентов, будет полезна страница для MSP: Redate.io позволяет обрабатывать несколько ящиков параллельно из единого интерфейса.
Другие сценарии, порождающие тот же артефакт
Восстановление из резервной копии - не единственный случай. Тот же артефакт дат появляется в других ситуациях:
- Импорт IMAP из Exchange (архивные ящики, повторно вставленные в Exchange Online)
- Миграция в Exchange Online с инструментами, использующими IMAP на стороне назначения
- Гранулярное восстановление из PST, экспортированного и реимпортированного (см. статью об импорте PST)
- Общие ящики, восстановленные после инцидента (см. исправление дат в общих ящиках)
Во всех этих случаях лежащий в основе механизм одинаков: повторная вставка не передаёт исходную дату (иногда добавляя сверху новый заголовок Received:), и почтовый клиент показывает эту новую дату как опорную.
Письма на месте, исходная дата сохранена в каждом сообщении. Запустите бесплатное сканирование на Redate.io, чтобы точно узнать, сколько писем затронуто в вашем ящике, и решить, стоит ли запускать коррекцию.