У письма три "даты". Не одна.
Когда речь заходит об изменении даты получения письма, большинство людей представляют себе редактирование какого-то поля, как при изменении даты создания файла в Windows. На деле всё сложнее. Каждое письмо содержит три отдельных слоя датирования, у каждого свои правила, свои ограничения, и свои последствия при вмешательстве.
Понять эти три слоя, значит понять, почему одни исправления технически корректны, а другие либо невозможны, либо мгновенно выявляются как фальсификация.
Слой 1: INTERNALDATE в IMAP
INTERNALDATE, это метаданные, хранящиеся на стороне сервера, за пределами самого сообщения. Они не входят в содержимое письма. IMAP-сервер устанавливает это значение при получении сообщения, и именно оно используется большинством почтовых клиентов для сортировки писем в списке.
Outlook, например, по умолчанию сортирует сообщения по INTERNALDATE. Gmail тоже, в определённых контекстах. Если INTERNALDATE некорректна, все письма в интерфейсе выглядят имеющими одну дату, независимо от того, что написано во внутренних заголовках сообщения.
INTERNALDATE устанавливается в момент размещения сообщения на сервере. По протоколу IMAP единственный способ её «изменить» косвенный: нужно использовать команду APPEND, чтобы разместить новую копию сообщения с нужной датой. Команды SETINTERNALDATE в IMAP не существует. Этот момент окажется важным чуть позже.
Слой 2: заголовок Date: (RFC 2822)
Это поле Date: в необработанных заголовках сообщения. Почтовый клиент устанавливает его в момент отправки, и оно путешествует вместе с письмом от сервера к серверу. По сути, это дата отправки, заявленная отправителем.
(Кстати, если Вы никогда не смотрели на необработанные заголовки письма, это довольно увлекательное чтение. В каждом сообщении около двадцати технических строк, которые 99% людей никогда не видели.)
Технически, ничто не мешает отправить письмо с заполненным задним числом или будущей датой в поле Date:. SMTP-серверы это поле не проверяют. Но принимающие серверы фиксируют реальное время поступления в заголовках Received:, что сразу создаёт несоответствие, заметное любому почтовому клиенту или инструменту анализа.
Слой 3: накопленные заголовки Received:
Каждый раз, когда SMTP-сервер передаёт сообщение, он добавляет заголовок Received: в верхнюю часть стека с временной меткой. Письмо, прошедшее через три сервера, будет иметь три заголовка Received:. Читаются они снизу вверх: самый старый внизу, самый новый вверху.
Именно здесь инструменты миграции и создают проблему. Когда BitTitan MigrationWiz, CloudM, imapsync или GSMMO переносят письмо, они заново загружают его на новый сервер через IMAP. Эта загрузка генерирует новый заголовок Received: с временной меткой даты миграции. В результате: самое старое письмо в ящике, отправленное в 2019 году, получает Received: с датой ноября 2024-го. А поскольку некоторые почтовые клиенты (Outlook в первую очередь) используют самый свежий Received: в качестве отображаемой даты...
Вот и вся проблема. 15 000 писем отображаются с одной датой миграции.
Можно ли действительно «изменить» эти даты?
Технически да, для INTERNALDATE (с ограничениями). Технически возможно, но бессмысленно для Date:. А про Received: стоит поговорить отдельно.
Переписать заголовок Received: просто. И мгновенно обнаружимо.
Заголовок Received:, это просто строка текста в сообщении. Её можно отредактировать как любой текстовый файл. Именно так просто, как кажется.
Но вот что происходит дальше.
Первая проблема: DKIM. Подпись DKIM (DomainKeys Identified Mail) вычисляется на основе набора заголовков сообщения, включая иногда Received:. Изменение подписанного заголовка инвалидирует подпись. Любой принимающий сервер, проверяющий DKIM, немедленно увидит, что сообщение было изменено. Это не тонкая фальсификация, это сигнал тревоги.
Вторая проблема: внутренние идентификаторы. Современные почтовые серверы (Google Workspace, Microsoft 365) присваивают каждому сообщению уникальный возрастающий внутренний идентификатор. Эти идентификаторы привязаны к INTERNALDATE и порядку получения. Изменение Received: без соответствия этим идентификаторам создаёт несоответствия, которые аудиторские инструменты обнаруживают без труда.
Третья проблема, более практичная: даже если Вы измените Received: в содержимом сообщения, INTERNALDATE останется неизменной, с датой IMAP-загрузки. Почтовый клиент продолжит отображать неправильную дату при сортировке. Вы изменили сообщение впустую.
Итог. Переписать Received: для подделки даты письма в злоумышленных целях: технически тривиально, обнаруживается за несколько секунд любым специалистом. Это не серьёзный путь.
Заголовок Date:: менять прошлое на бумаге
Та же логика применима к Date:. Его можно изменить в теле сообщения. Но заголовки Received:, заверенные промежуточными серверами, остаются нетронутыми и рассказывают другую историю. Временная цепочка оказывается противоречивой. Любой аналитик или суд, сравнивающий эти поля, увидит это немедленно.
Если быть точным, это не мешает некоторым почтовым клиентам отображать изменённый Date: при прямом открытии файла .eml. Но в контексте живого почтового сервера с аутентификацией и журналами изменение очевидно.
Миграция IMAP: единственный контекст, где исправление дат оправданно
Есть один, и только один, случай, когда изменение даты получения письма не просто возможно, но и технически обосновано: исправление повреждений, нанесённых некорректно выполненной IMAP-миграцией.
Конкретная ситуация. Вы только что перенесли 80 почтовых ящиков Exchange в Microsoft 365. Миграция завершилась в пятницу вечером. В понедельник утром начинают поступать тикеты: "У всех писем одна дата", "Не могу найти письмо за прошлый год", "Вся переписка с клиентом сломалась". 80 пользователей парализованы, и руководство ждёт ответа.
В этом контексте проблема документирована, поддаётся идентификации, и её причина ясна: инструмент миграции добавил Received: с датой дня миграции, а некоторые почтовые клиенты используют этот новый заголовок как отображаемую дату. При этом оригинальный заголовок Date: в каждом сообщении нетронут. Он никогда не изменялся. Он по-прежнему содержит правильную исходную дату отправки.
Исправление, таким образом, не является фальсификацией: это восстановление. За основу берутся истинные данные (оригинальный Date:) для восстановления согласованных метаданных. Это принципиально отличается от попытки выдать письмо 2024 года за письмо 2019-го.
Для более детального изучения механизмов конкретных инструментов, подробные разборы доступны здесь: исправление дат BitTitan в Microsoft 365, исправление дат CloudM в Outlook, или исправление дат imapsync в Google Workspace.
Почему писать скрипт самостоятельно рискованно
Базовая логика доступна. Любой IT-администратор, проводивший время на форумах по IMAP, может восстановить общий подход. Это не проблема.
Проблема в разрыве между скриптом, работающим на 50 тестовых письмах, и скриптом, обрабатывающим 40 000 сообщений в продакшене без потери ни одного письма, без повреждения ни одного вложения, без разрыва ни одной цепочки переписки.
Несколько конкретных случаев, которые самописные скрипты обычно не обрабатывают:
- Письма с подписью S/MIME: подпись охватывает содержимое и заголовки. Любое изменение структуры сообщения инвалидирует подпись. Неаккуратно исправленное подписанное письмо придёт с пометкой "недействительная подпись".
- Зашифрованные PGP-сообщения: та же категория проблем, с потенциально худшими последствиями в зависимости от реализации.
- Не-ASCII-кодировки в заголовках: RFC 2047 описывает кодирование специальных символов в заголовках. Скрипт, манипулирующий заголовками без учёта этих случаев, незаметно испортит темы писем с кириллицей, японскими иероглифами или арабскими именами.
- Ограничения API: Google Workspace и Microsoft 365 применяют агрессивный throttling. В три часа ночи пакетная обработка 10 000 писем, получившая ошибку 429 Too Many Requests без экспоненциального backoff, оставит половину ящиков в полуисправленном состоянии.
- Повреждённые MIME-границы: многочастные сообщения с вложениями имеют точные MIME-границы. Неверная регенерация сделает вложения нечитаемыми.
И вопрос, который ни один самописный скрипт не решает: как убедиться, что каждое исправленное письмо цело? Скрипт, изменяющий 40 000 сообщений без индивидуальной проверки, это ставка. Ставка на данные, которые пользователи нередко считают незаменимыми.
Статья о доступных способах исправить даты после миграции разбирает различные подходы, включая их соответствующие ограничения.
Что делает Redate.io в этом контексте
Redate.io разработан именно для этого случая: исправление дат, повреждённых IMAP-миграцией, в масштабе, без риска для целостности сообщений.
Сервис подключается напрямую к затронутым ящикам (Google Workspace через делегирование домена, Microsoft 365 через Azure AD, или напрямую по IMAP), бесплатно сканирует сообщения с неверными датами, затем применяет проприетарный многоступенчатый конвейер коррекции, обрабатывающий описанные выше пограничные случаи. Каждое письмо проверяется индивидуально после исправления. Оригиналы остаются в видимой резервной папке в течение 30 дней.
Сопоставление сигнатур охватывает сотни известных инструментов миграции: BitTitan MigrationWiz, CloudM, imapsync, GSMMO и их варианты. Обнаружение точное: Redate.io не трогает письма с корректными датами.
Модель оплаты проста: единовременный платёж за почтовый ящик, без подписки. Диагностическое сканирование бесплатно, что позволяет оценить масштаб проблемы до принятия каких-либо решений.
Если Вы сталкиваетесь с ящиками, затронутыми этой проблемой, статья о неправильных датах в Outlook после миграции подробно описывает наиболее частые симптомы и как отличить их от других причин.
Готовы оценить масштаб проблемы в Ваших почтовых ящиках? Запустите бесплатное сканирование на Redate.io и узнайте точно, сколько писем затронуто, до любых исправлений.