IMAP INTERNALDATE: чому дати ламаються

6 min

Три дати всередині кожного листа

Кожний лист, збережений на IMAP-сервері, несе щонайменше три окремі значення дати. Розуміння того, як ці дати працюють і як поштові клієнти обирають, яку показувати, є ключем до розуміння того, чому міграція ламає дати. Ця стаття - поглиблений технічний аналіз системи дат IMAP, призначений для ІТ-адміністраторів та всіх, хто хоче зрозуміти першопричину проблем з датами після міграції.

1. Заголовок "Date" RFC 2822

Заголовок "Date" визначено у RFC 2822 (формат інтернет-повідомлень). Він встановлюється поштовим клієнтом відправника у момент створення та відправлення повідомлення. Цей заголовок є частиною самого тіла повідомлення, він подорожує з повідомленням і ніколи не змінюється поштовими серверами на шляху доставки. Типовий заголовок Date виглядає так:

Date: Mon, 15 Jan 2024 09:32:17 +0100

Заголовок Date представляє "дату відправлення" повідомлення. Це найнадійніша дата, оскільки вона встановлюється одноразово і ніколи не змінюється. Однак вона відображає годинник відправника, який може бути неправильно налаштований. У рідкісних випадках заголовок Date може бути повністю відсутнім (особливо в автоматизованих системних повідомленнях або неправильно сформованих повідомленнях).

2. IMAP INTERNALDATE

INTERNALDATE визначено у RFC 3501 (протокол IMAP4rev1). Це значення метаданих на боці сервера, що представляє дату й час доставки повідомлення на сервер. На відміну від заголовка Date, INTERNALDATE не є частиною самого повідомлення. Він зберігається окремо IMAP-сервером як метадані.

Коли лист доставляється звичайним чином (не через міграцію), IMAP-сервер встановлює INTERNALDATE на поточний час доставки. Це значення близько відповідає заголовку Date, зазвичай з різницею у кілька секунд або хвилин. Поштові клієнти часто використовують INTERNALDATE як "дату отримання", оскільки він відображає момент, коли сервер фактично отримав повідомлення.

І ось де стає цікаво. Коли повідомлення вставляється через команду IMAP APPEND (що використовують інструменти міграції), команда APPEND дає клієнту змогу явно вказати INTERNALDATE. Добре розроблені інструменти міграції використовують цю можливість для збереження оригінального INTERNALDATE з сервера-джерела. Але навіть коли INTERNALDATE правильно встановлено, проблема з заголовком "Received" (описана нижче) все одно може перекрити відображувану дату у багатьох клієнтах.

3. Ланцюжок заголовків "Received"

Щоразу, коли лист проходить через поштовий сервер, цей сервер додає заголовок "Received" на початок повідомлення. Це створює ланцюжок заголовків Received, що документує шлях листа від відправника до отримувача. Найновіший (зверху) показує останній сервер, що обробив повідомлення, а найстаріший (знизу) - перший.

Звичайний лист може мати від 3 до 6 заголовків Received, що документують подорож від вихідного сервера відправника через ретранслятори до вхідного сервера отримувача. Кожний заголовок Received включає часовий штамп. Ось спрощений приклад:

Received: from mx.recipient.com; Mon, 15 Jan 2024 09:32:22 +0000
Received: from relay.sender.com; Mon, 15 Jan 2024 09:32:20 +0000
Received: from smtp.sender.com; Mon, 15 Jan 2024 09:32:18 +0000
Date: Mon, 15 Jan 2024 09:32:17 +0100

Як поштові клієнти обирають, яку дату показувати

Outlook (Desktop, Web, Mobile)

Microsoft Outlook використовує комбінацію INTERNALDATE та найновішого заголовка "Received" для визначення дати "Отримання", що відображається у скриньці. На практиці Outlook схильний надавати перевагу часовому штампу найновішого заголовка Received для колонки "Отримано". Колонка "Відправлено" використовує заголовок Date. Оскільки Outlook за замовчуванням сортує за колонкою "Отримано", саме часовий штамп заголовка Received бачать користувачі першим.

Apple Mail

Apple Mail на macOS та iOS використовує переважно IMAP INTERNALDATE для відображення дати. Якщо INTERNALDATE було правильно збережено під час міграції, Apple Mail може показувати правильну дату, але лише якщо INTERNALDATE було явно встановлено під час операції APPEND. Якщо інструмент міграції не встановив INTERNALDATE, сервер за замовчуванням використовує час вставки (дату міграції). Для деталей впливу на користувачів Apple Mail див. Apple Mail: хибна дата після міграції.

Thunderbird

Mozilla Thunderbird пропонує найбільшу гнучкість. Він може відображати і "Date" (з заголовка Date), і "Отримано" (з заголовків Received). За замовчуванням Thunderbird показує значення заголовка Date, що означає, що дати можуть виглядати правильно у Thunderbird навіть тоді, коли вони хибні в Outlook. Колонка "Отримано" у Thunderbird завжди показує дату міграції. Див. Thunderbird: хибна дата після міграції для деталей.

Вебінтерфейс Gmail

Веб-клієнт Gmail використовує заголовок Date для основного відображення дати. Це означає, що вебінтерфейс Gmail часто показує правильні дати навіть після міграції. Але IMAP INTERNALDATE на сервері Gmail все одно некоректний, що зачіпає кожний IMAP-клієнт, підключений до цього облікового запису Gmail. Різниця між вебінтерфейсом Gmail та Outlook або Apple Mail - часте джерело плутанини та тривалого марного усунення несправностей адміністраторами.

Чому IMAP APPEND ламає дати

Що відбувається під час міграції

Коли інструмент міграції переміщує лист з Сервера A на Сервер B, інструмент підключається до Сервера A через IMAP та завантажує необроблене повідомлення, потім підключається до Сервера B та використовує команду APPEND для його вставки. Під час цієї вставки Сервер B обробляє вхідне повідомлення та додає новий заголовок Received з поточним часовим штампом: датою міграції. Це стандартна поведінка IMAP, визначена у протоколі. Сервер обробляє кожний APPEND як нову доставку повідомлення.

Результат: забруднений ланцюжок заголовків

Після міграції заголовки Received листа виглядають так:

Received: from migration-tool; Fri, 11 Apr 2025 14:22:08 +0000
Received: from mx.recipient.com; Mon, 15 Jan 2024 09:32:22 +0000
Received: from relay.sender.com; Mon, 15 Jan 2024 09:32:20 +0000
Date: Mon, 15 Jan 2024 09:32:17 +0100

Заголовок Received від інструмента міграції тепер є найвищим записом. Будь-який поштовий клієнт, що використовує найновіший заголовок Received для визначення дати відображення (зокрема, Outlook), покаже "11 квітня 2025" замість "15 січня 2024". Оригінальний заголовок Date та оригінальні заголовки Received все ще недоторкані нижче, але вони більше не займають позицію, якій поштові клієнти надають перевагу.

Навіть правильна обробка INTERNALDATE не запобігає цьому

Деякі інструменти міграції правильно встановлюють INTERNALDATE під час APPEND. Наприклад, imapsync явно зберігає INTERNALDATE сервера-джерела. Але заголовок Received додається сервером призначення, а не інструментом міграції. Інструмент міграції не має контролю над цією поведінкою. Навіть з ідеальним збереженням INTERNALDATE найвищий заголовок Received все одно містить дату міграції, і клієнти, як-от Outlook, все одно показують хибну дату.

То що ж конкретно з цим можна зробити?

Які інструменти міграції додають заголовки Received

Усі інструменти міграції IMAP спричиняють цю проблему, оскільки заголовок Received додається сервером призначення, а не самим інструментом. Зміст доданого заголовка залежить від інструмента та сервера.

BitTitan MigrationWiz додає заголовок Received, що містить "mx.migrationwiz.com". CloudM Migrate додає заголовки з посиланням на "cloudm.io". imapsync спричиняє загальний заголовок Received від сервера призначення. GSMMO додає заголовки з посиланням на "gmailapi.google.com".

Виправлення: відновлення правильних дат

Позитивна новина полягає в тому, що правильна інформація про дату все ще існує у кожному листі. Оригінальний заголовок Date недоторканий. Оригінальні заголовки Received недоторкані. Проблема в тому, що забруднюючий заголовок розміщений над ними.

Пропрієтарний рушій корекції Redate.io аналізує повний ланцюжок заголовків кожного ураженого листа, застосовуючи зіставлення сигнатур з сотнями відомих сигнатур інструментів міграції для точного визначення, які заголовки потребують виправлення. Багатоступеневий процес аналізу обробляє складні випадки, що спричиняють невдачу простіших підходів: повідомлення з підписами S/MIME, зашифрований вміст PGP, структури multipart/alternative, проблеми Content-Transfer-Encoding, заголовки non-ASCII (RFC 2047), надмірно великі вкладення та пошкоджені межі MIME.

Після виправлення кожний лист проходить процес перевірки цілісності для підтвердження, що структура, вміст та вкладення повідомлення збережені ідентично. Оригінали зберігаються у видимій теці резервного копіювання протягом 30 днів.

Чи можна написати скрипт для такого виправлення самостійно? Технічно так. Але різниця між "працює для 95% листів" та "працює для 100% листів без пошкодження жодного" - це місяці розробки. А коли йдеться про повну поштову скриньку людини, показник невдачі у 5% означає сотні непомітно пошкоджених повідомлень без можливості перевірити, що саме пішло не так.

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