누구나 겪는 그 증상
Microsoft 365 또는 Google Workspace로 IMAP 마이그레이션을 막 끝냈습니다. 월요일 아침, 티켓이 쏟아집니다. "이메일이 전부 같은 날짜예요", "메일함 순서가 완전히 뒤죽박죽이에요", "예전 메일을 아무것도 못 찾겠어요." Outlook을 열어보면, 실제로 수천 개의 이메일이 지난 주말 날짜로 표시되어 있습니다. 메일이 발송된 날짜가 아니라, 마이그레이션이 실행된 날짜로요.
이건 Outlook 버그가 아닙니다. IMAP 프로토콜과 마이그레이션 도구의 작동 방식에서 비롯된 직접적인 결과입니다. 왜 그런지 이해하려면 뚜껑을 열어봐야 해요.
이메일 하나에 날짜가 세 개
이메일은 겉보기보다 훨씬 복잡한 구조를 갖고 있어요. 헤더, 본문, 첨부파일... 그리고 서로 다른 타임스탬프가 여럿 공존합니다. (이메일의 원시 헤더를 직접 읽어본 적이 있다면, 그게 가벼운 독서거리가 아니라는 걸 잘 알 겁니다.)
Date: 헤더 (RFC 2822)
발신자가 메일을 보낼 때 메시지에 직접 기록한 날짜입니다. RFC 2822 규격으로 정의되며, 이런 형식입니다:
Date: Tue, 14 Mar 2023 09:42:17 +0100
이 헤더는 메시지 본문에 고정되어 있습니다. 누군가 원시 메시지 내용을 직접 수정하지 않는 한 절대 바뀌지 않아요. 엄밀한 의미에서 "발송 날짜"가 바로 이겁니다.
Received: 헤더 (네트워크 경유마다 추가됨)
이메일이 경유하는 각 서버는 메시지 맨 위에 Received: 헤더를 추가합니다. 자신의 날짜를 담아서요. 세 서버를 거친 이메일에는 Received: 헤더가 세 개 쌓입니다. 가장 최근 것이 항상 맨 위에 옵니다. 대략 이런 모습이에요:
Received: from mail.example.com ([93.184.216.34])
by mx.google.com with ESMTPS
id x1234abcd.2024.06.15.08.31.02;
Sat, 15 Jun 2024 08:31:02 +0000 (UTC)
결국, BitTitan MigrationWiz, CloudM, imapsync, GSMMO 같은 마이그레이션 도구가 이메일을 원본 서버에서 대상 서버로 옮길 때, 이 도구들도 "네트워크 경유 지점"처럼 동작합니다. 마이그레이션 날짜와 시간을 담은 새 Received: 헤더를 스택 맨 위에 주입하는 거죠.
IMAP INTERNALDATE
세 번째 날짜입니다. 그리고 문제의 핵심이 여기 있어요. INTERNALDATE는 메시지 내용과 별개로 IMAP 서버 측에 저장되는 메타데이터입니다. 이메일이 메일함에 배달(또는 삽입)된 날짜를 나타내요. 마이그레이션 도구가 이메일을 삽입할 때, INTERNALDATE에 어떤 값을 줄지 도구 스스로 결정합니다. 그리고 많은 경우, 원래 날짜가 아닌 마이그레이션 시점의 날짜를 씁니다.
모든 문제가 여기서 시작됩니다.
Outlook이 마이그레이션 날짜를 표시하는 이유
Outlook은 "받은 날짜" 열을 표시할 때 INTERNALDATE를 사용합니다. 이건 Outlook의 기본 동작이고, IMAP 규격과도 일치합니다. INTERNALDATE는 원래 메일함 수신 날짜를 나타내도록 설계되어 있으니까요. 정상적인 상황(실제로 도착하는 이메일)에서는 INTERNALDATE와 Date: 헤더의 날짜가 거의 일치합니다. 둘이 일관성을 유지하는 거예요.
마이그레이션이 잘못된 후에는, 가져온 모든 이메일의 INTERNALDATE가 2024년 6월 14일 밤(또는 마이그레이션 날짜가 뭐든)을 가리킵니다. Outlook이 이 값을 읽어 "받은 날짜" 열에 표시하면, 결과는 참담합니다. 45,000개의 이메일이 같은 날 저녁에 수신된 것처럼 보이는 거죠.
정확히 말하면, 스택에서 가장 위에 있는 Received: 헤더(가장 최근 것)도 일부 설정에서 표시에 영향을 미칩니다. 하지만 IMAP 동기화 모드에서 Outlook의 "받은 날짜" 열을 결정하는 주된 요소는 어디까지나 INTERNALDATE입니다.
Outlook에서 "보낸 날짜" 열 추가 우회책
IT 관리자 대부분이 이 문제를 처음 발견하면 클라이언트 측 우회책부터 찾습니다. 실제로 그런 방법이 있기도 하고요.
Outlook에서는 폴더의 열 표시를 수정해서 "받은 날짜" 열을 "날짜" 또는 "보낸 날짜" 열로 대체(또는 추가)할 수 있습니다. "날짜" 열은 INTERNALDATE가 아닌 메시지의 Date: 헤더를 직접 읽습니다. Date: 헤더는 마이그레이션으로 건드려지지 않았으니, 원래 날짜가 다시 나타나죠.
Outlook 데스크톱(Microsoft 365 버전) 기준으로: 메시지 목록의 열 헤더를 오른쪽 클릭하고 "보기 설정"을 선택한 다음, 열을 수정해서 "받은 날짜"를 제거하고 "날짜"를 추가하면 됩니다. GPO로 일괄 배포도 가능해요.
표면적으로는 시각적 문제를 해결한 것처럼 보입니다. 실제로는 동맥에 반창고를 붙이는 수준입니다.
이 우회책의 현실적인 한계
모바일 및 웹 클라이언트
iOS, Android의 Outlook과 Outlook Web App(OWA)은 동일한 커스터마이즈 옵션을 제공하지 않습니다. Windows PC에 배포한 보기 변경이 모바일에는 반영되지 않아요. 휴대폰으로 이메일을 확인하는 사용자들은 여전히 마이그레이션 날짜를 보게 됩니다. 중간 규모 기업이라면 아마 사용자의 절반 정도가 해당되겠죠.
검색 기능
Outlook 검색은 Windows Search 인덱스(또는 Exchange/Microsoft 365 서버 측 인덱스)를 사용합니다. 이 인덱스는 Date: 헤더가 아닌 INTERNALDATE를 기준으로 구축됩니다. 사용자가 "2022년 1월 이메일"을 검색하면, INTERNALDATE가 2022년 1월인 이메일을 반환합니다. Date: 헤더가 2022년 1월인 이메일이 아니라요. 결과적으로 오래된 이메일이 날짜 필터에서 전혀 나오지 않습니다. 표시 열을 바꿔도 이건 전혀 해결이 안 돼요.
메일 규칙
Outlook 규칙("...날짜 이전에 수신된 경우", "...날짜 이후에 수신된 경우")도 INTERNALDATE를 사용합니다. INTERNALDATE가 수정되지 않은 상태에서 날짜 범위 기반의 정렬 또는 보관 규칙은 마이그레이션 후 제대로 동작하지 않습니다.
규정 준수 및 eDiscovery
아마 가장 심각한 부분입니다. 규정 준수 도구, 법적 아카이빙, eDiscovery 도구(예: Microsoft Purview)는 법적 쿼리의 날짜 기준으로 INTERNALDATE를 사용합니다. 개인정보보호법(PIPA, 개인정보 보호법)이나 전자 증거 보전 의무를 따라야 하는 기업이라면, 손상된 INTERNALDATE는 실제 법적 문제로 이어질 수 있습니다. "특정 기간의 이메일을 모두 제출하라"는 요청에 올바른 결과가 반환되지 않을 수 있으니까요.
서드파티 도구들
CRM, 티켓팅 시스템, 아카이버... IMAP이나 Microsoft 365/Google Workspace API를 통해 메일 서버에 연결되는 모든 것이 INTERNALDATE를 읽습니다. Outlook 보기를 바꿔봤자 이런 시스템에는 아무런 영향이 없어요.
유일한 진짜 해결책: 서버 수준에서 수정하기
Outlook에서 보낸 날짜 기준으로 정렬하는 것은 해결책이 아닙니다. 반창고일 뿐이에요. 진짜 수정은 클라이언트 보기가 아닌 서버의 메타데이터 수준에서 이루어져야 합니다.
구체적으로는, 각 이메일의 INTERNALDATE를 원본 Date: 헤더의 날짜와 일치하도록 수정해야 합니다. 원본 Date: 헤더는 마이그레이션으로 삭제되지 않고 메시지 안에 그대로 남아 있습니다. 실제 날짜 정보가 바로 거기 있는 겁니다. 덕분에 수정이 가능한 거고요.
Google Workspace에서는 Gmail API가 이 메타데이터를 직접 다룰 수 있는 internalDate 파라미터를 제공합니다. Microsoft 365에서는 메커니즘이 다르지만 원하는 결과는 같습니다. 표준 IMAP 서버에서는 메시지 삽입 시 날짜를 지정하는 방식이 규격으로 정의되어 있습니다.
현실적으로, 프로덕션 환경의 수만 개 이메일에 데이터 손실 없이, 중복 없이, 스레드나 레이블을 깨지 않고, 엣지 케이스(S/MIME 서명 메시지, 복잡한 MIME 구조, RFC 2047 비ASCII 인코딩, 용량 큰 첨부파일)까지 처리하면서 이 작업을 수행하는 건 완전히 다른 차원의 이야기입니다. 테스트 이메일 50개에서 돌아가는 스크립트가 40,000개짜리 메일함에서는 버티지 못합니다. 429 오류(API 할당량 초과) 처리, 새벽 2시에 발생하는 네트워크 타임아웃, 마이그레이션 후 MIME 구조가 이미 일부 손상된 메시지들... 이 모든 게 본격적인 엔지니어링을 요구합니다.
바로 이것이 Redate.io가 하는 일입니다. 독점 수정 엔진이 각 이메일의 헤더 체인을 분석하고, 신뢰할 수 있는 원본 날짜를 식별한 후, 메시지 내용을 건드리지 않고 메타데이터만 정밀하게 수정합니다. 수정된 각 이메일은 개별적으로 검증됩니다. 원본은 30일간 백업 폴더에 보관되어 언제든 롤백이 가능합니다. 직접 만든 스크립트에는 없는 기능이죠.
원인이 된 마이그레이션 도구 파악하기
마이그레이션 출처와 무관하게 증상은 동일하게 나타나지만, 사용된 도구에 따라 세부 사항이 다릅니다. BitTitan MigrationWiz, CloudM, imapsync, GSMMO는 각각 주입하는 Received: 헤더에 고유한 서명을 남깁니다. Redate.io의 분석 파이프라인은 수백 개의 알려진 마이그레이션 도구 서명 데이터베이스를 유지하며, 마이그레이션 헤더를 정상적인 전송 체인의 나머지 부분과 구별합니다.
어떤 도구로 마이그레이션이 진행됐는지 모르는 경우(다른 MSP로부터 인수인계 받을 때 종종 있는 일입니다), Redate.io의 무료 스캔으로 영향받은 메일함을 파악하고 수정 전에 수정 대상 이메일 수를 추정할 수 있습니다.
도구별 상세 가이드도 있습니다: Outlook에서 imapsync 날짜 수정, Outlook에서 BitTitan 날짜 수정, Outlook에서 CloudM 날짜 수정 가이드를 참고하세요.
지금 당장 해야 할 것
마이그레이션 후에 이 글을 읽고 있다면, 좋은 소식이 있습니다. 원본 Date: 헤더는 각 이메일 안에 그대로 살아 있습니다. 실제 날짜 정보는 이미 거기 있어요, 모든 메시지 안에. 문제는 내용이 아닌 메타데이터에 있고, 메타데이터는 수정할 수 있습니다.
문제의 작동 원리를 더 깊이 이해하고 싶다면 IMAP INTERNALDATE: 날짜가 깨지는 이유 글을, 마이그레이션 후 Outlook 날짜 오류에 대한 전반적인 상황이 궁금하다면 Outlook 마이그레이션 날짜 오류 완전 가이드를 참고하세요.
메일함 날짜를 수정할 준비가 되셨나요? Redate.io에서 무료 스캔을 시작하세요. 수정 전에 영향받은 이메일을 파악하고 수정 대상 규모를 미리 확인할 수 있습니다.