Наступного ранку після відновлення: тікети від користувачів
Ви щойно завершили відновлення поштової скриньки через 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. Вона служить для вставки повідомлення у поштову скриньку. Саме це і використовує інструмент відновлення: він бере збережене повідомлення і вставляє його в цільову скриньку.
Ця команда дозволяє інструменту передати дату разом із повідомленням. Якщо інструмент передає оригінальну дату повідомлення, поштова скринька зберігає її: так роблять 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 appliance...) і потім були повторно вставлені. Користувач цього не очікує: для нього це "його" листи, що повернулися, а не імпортовані дані.
Але технічно механізм той самий. Повторна вставка, яка не передає оригінальну дату, породжує ті самі артефакти. І виправлення теж слідує тій самій логіці.
Як кожен інструмент обробляє (або не обробляє) 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 для своїх клієнтів, стикаються з цією проблемою досить регулярно - особливо після ransomware-інцидентів, де терміново відновлюють кілька сотень скриньок одночасно. Це не той момент, коли хочеться виявити, що всі дати неправильні.
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 о 2 ночі під час пакетної операції).
Коротко кажучи: відновлення спрацювало. Дані є. Виправляти потрібно артефакт дати, а не саме відновлення.
Виправляти самостійно: конкретні ризики
Зрозуміти проблему - одна річ. Виправити її на 80 000 листів без втрати жодного - зовсім інша.
Python-скрипт, що перебирає IMAP-повідомлення і виправляє дати, може здатися реалістичним варіантом. На 50 тестових листах він спрацює чудово. У продуктивному середовищі - інша справа. Граничні випадки накопичуються: листи, підписані S/MIME (зміна заголовку анулює криптографічний підпис), PGP-зашифровані повідомлення, multipart-структури з нестандартними MIME-межами, заголовки в кодуванні RFC 2047 (не-ASCII), вкладення розміром 40 МБ, що переповнюють пам'ять скрипту. Плюс листи з кількома доданими заголовками Received: (якщо відновлення було частково перезапущено, що трапляється) - вони потребують складнішої логіки виявлення.
Насправді найбільший ризик не в скрипті, що падає: це скрипт, що працює без видимих помилок, але продукує пошкоджені повідомлення. Розірвані ланцюжки листувань. Дублікати. Відокремлені вкладення. Про які Ви дізнаєтеся лише через кілька тижнів, коли користувач спробує знайти важливий лист.
І як Ви перевіряєте, що кожен виправлений лист реально цілий після модифікації? Самописний скрипт, як правило, цього не робить.
Що Redate.io робить інакше
Redate.io аналізує ланцюжок заголовків кожного листа для виявлення артефактів повторної вставки - з відновлення Veeam, міграції BitTitan чи ручного імпорту. Власному рушію корекції не потрібно знати, який саме інструмент спричинив помилку: він шукає листи, чия відображена дата не відповідає оригінальній даті, тож навіть невідомий інструмент буде виявлений.
Перш ніж щось виправляти, Redate.io сканує всю скриньку і надає звіт: скільки листів зачеплено, яка неправильна дата, яка початкова дата виявлена. Це сканування безкоштовне. Ви бачите масштаб проблеми перед тим, як приймати рішення.
Кожен лист перевіряється індивідуально після виправлення. Оригінали ніколи не видаляються Redate.io: вони залишаються у видимій резервній папці вашої скриньки, доки ви самі не вирішите їх прибрати.
Кожен користувач підписується у свій обліковий запис Microsoft, і Redate.io відкриває саме цю скриньку з тими правами доступу, які надає цей вхід (для Google Workspace - через делегування домену), без транзиту листів через проміжні сервери. Виправлення відбувається на місці, у скриньці, без експорту та повторного імпорту.
Для MSP-провайдерів, що одночасно обслуговують кількох постраждалих клієнтів, дивіться сторінку для MSP: Redate.io дозволяє обробляти кілька скриньок паралельно з єдиного інтерфейсу.
Інші сценарії, що породжують той самий артефакт
Відновлення з інструменту резервного копіювання - не єдиний випадок. Той самий артефакт дати з'являється в інших ситуаціях:
- Імпорт IMAP з Exchange (заархівовані скриньки, повторно вставлені в Exchange Online)
- Міграція до Exchange Online з інструментами, що використовують IMAP на стороні призначення
- Гранулярне відновлення з PST, що був експортований і повторно імпортований (дивіться статтю про імпорт PST)
- Спільні поштові скриньки, відновлені після інциденту (дивіться виправлення дат у спільних скриньках)
У всіх цих випадках підлеглий механізм однаковий: повторна вставка, що не передає оригінальну дату (іноді з новим заголовком Received: зверху), і поштовий клієнт, що показує цю нову дату як референсну.
Листи є, початкова дата збережена в кожному повідомленні. Запустіть безкоштовне сканування на Redate.io, щоб побачити точно, скільки листів зачеплено у Вашій скриньці, і вирішіть, чи запускати виправлення.