임시 메일 서비스의 내부: 이메일이 SMTP에서 화면까지 오는 과정
PureTempMail 팀
PureTempMail을 만들고 운영하는 엔지니어들
처리 과정을 공개하는 이유
일회용 이메일 서비스는 대부분 속을 알 수 없는 상자와 같습니다. 주소를 입력하면 메일이 나타나지만, 그 사이에 무슨 일이 벌어지는지는 알 길이 없습니다. 누가 메시지를 들여다보는지, 어디에 저장되는지, 정말로 지워지기는 하는지 알 수 없습니다. "임시 메일 서비스를 믿어도 되는가"라는 질문에 대한 정직한 답이 결국 이런 세부 사항에 달려 있기에, PureTempMail이 어떻게 동작하는지 구성 요소 하나하나까지 공개하기로 했습니다.
아래 내용은 모두 지금 이 웹사이트를 실제로 돌리고 있는 시스템에 대한 설명입니다. 홍보용으로 단순화한 도식이 아니라, 이 시스템을 직접 만들고 운영하는 팀이 쓴 글입니다. 무언가를 얻기 위해 다른 것을 포기한 대목에서는 무엇을 왜 그렇게 정했는지 밝혔습니다.
1단계: SMTP 핸드셰이크, 쓸모없는 메일 대부분이 걸러지는 곳
인터넷의 모든 이메일은 SMTP 대화로 시작합니다. PureTempMail은 외부와 맞닿은 지점에서 보안을 강화한 SMTP 서버를 25번 포트에 띄워 두고, TLS를 지원하는 발신 서버와는 암호화된 연결로 주고받습니다. 메일 서버가 접속해 수신자를 알려 와도 메시지를 무턱대고 받아들이지는 않습니다.
본문이 단 1바이트도 넘어오기 전인 RCPT TO 단계에서 수신자 주소를 살아 있는 메일함 목록과 대조합니다. 아무도 만든 적 없는 주소이거나 이미 만료된 메일함이라면 그 자리에서 영구 SMTP 오류로 연결을 거부합니다. 일단 받아 둔 다음 조용히 버리는 일은 없습니다. 이렇게 앞단에서 걸러 내는 것은 의도적인 설계 원칙이기도 합니다. PureTempMail은 수신 전용이라 PureTempMail 주소로는 메일을 보낼 방법 자체가 없습니다. 그래서 이 서비스는 스팸이나 피싱, 괴롭힘에 악용될 수 없습니다.
2단계: 수신과 처리 사이에 놓인 큐
받아들인 메시지를 SMTP 서버 안에서 곧바로 해석하지는 않습니다. 대신 원본 메일을 메시지 큐로 흘려보내고 SMTP 대화는 즉시 끝냅니다. 이유는 시간입니다. 발신 서버는 몇 초 안에 응답이 오기를 기대하지만, 첨부파일이 붙은 큰 메일을 해석하는 데는 그보다 훨씬 오래 걸릴 수 있습니다. 두 단계를 떼어 놓으면 메일이 한꺼번에 몰려도 응답이 끊기거나 메시지가 사라지는 일이 없습니다. 큐가 순간적인 폭증을 받아 내고, 소비자 프로세스가 차례차례 처리하기 때문입니다.
이 소비자 프로세스가 원본 MIME 구조를 해석해 제목과 발신자, HTML 본문과 일반 텍스트 본문, 첨부파일을 뽑아냅니다. 첨부파일은 무작위로 만든 이름을 붙여 격리된 저장소에 기록합니다. 발신자가 정한 파일명을 그대로 쓰는 일은 절대 없으며, 이것만으로 경로 조작 계열의 공격이 통째로 막힙니다. 메시지의 메타데이터와 본문은 메일함의 만료 시각에 묶인 채 데이터베이스에 들어갑니다.
3단계: 마케팅 메일이 사용자를 추적하지 못하게 하는 HTML 정제
HTML 메일은 받은편지함에서 가장 위험한 요소입니다. 흔한 마케팅 메일에는 원격 이미지(언제 어디서 열었는지 알려 주는 추적 픽셀)와 외부 스타일시트, 때로는 스크립트까지 들어 있습니다. 메일을 화면에 보여 주기 전에 엄격한 허용 목록을 적용한 HTML 정제기를 거치게 합니다. 스크립트는 제거하고, 외부 리소스는 통째로 걷어 내며, 안전한 인라인 스타일만 남깁니다. 추적 픽셀은 애초에 불려 오지 않기 때문에 발신자는 메일이 열렸는지조차 알 수 없습니다.

정제를 마친 결과는 브라우저에서 완전히 격리된 샌드박스 iframe 안에 표시됩니다. 설령 악의적인 요소가 정제를 뚫고 살아남더라도, 샌드박스가 주변 페이지와 메일함 세션은 물론 브라우저의 다른 어떤 것에도 손대지 못하게 막습니다.
4단계: Server-Sent Events로 실시간 전달
임시 메일 사이트는 대부분 페이지를 새로고침하게 하거나 몇 초마다 서버에 새 메일이 있는지 물어봅니다. PureTempMail은 브라우저와 SSE(Server-Sent Events)로 연결 하나를 길게 열어 둡니다. 소비자 프로세스가 메시지 저장을 끝내는 순간 그 연결로 이벤트가 밀려 들어오고 메일이 받은편지함에 나타납니다. 발신자가 보낸 시점으로부터 대개 1~3초입니다. 2단계 인증 코드나 유효 시간이 짧은 활성화 링크처럼 시간을 다투는 상황에서는 이 몇 초가 큰 차이를 만듭니다.
연결은 주기적으로 신호를 주고받아 끊어진 상태를 감지하고, 네트워크가 끊기면 클라이언트가 간격을 점점 늘려 가며 자동으로 다시 접속합니다. Android와 iOS 앱도 같은 이벤트 스트림을 쓰기 때문에 어느 기기에서 보든 새 메시지가 같은 순간에 도착합니다.
5단계: 만료는 곧 실제 삭제
모든 메일함은 화면에 남은 시간이 표시된 채로 만들어지고, 살아 있는 동안에는 언제든 연장할 수 있습니다. 만료되고 나면 몇 분마다 도는 정리 작업이 뒤를 이어받습니다. 먼저 첨부파일을 디스크에서 지우고, 그다음 메일함과 그에 딸린 모든 메시지의 데이터베이스 행을 연쇄적으로 삭제합니다.
보관소도 없고, 만료된 메일의 백업도 없으며, 데이터를 눈에 안 보이게 남겨 두는 이른바 소프트 삭제 표시도 두지 않습니다. 정책이 아니라 구조 자체로 강제하는 데이터 최소화입니다. 더 이상 존재하지 않는 것은 넘겨줄 수도, 유출할 수도, 잃어버릴 수도 없습니다.
전체 과정은 이것으로 끝입니다. SMTP 핸드셰이크, 큐, 파서, 정제기, 푸시 이벤트, 그리고 삭제 작업. 각 단계는 10분만 쓰고 버릴 주소가 그 뒤로 아무런 부담도 남기지 않도록 하기 위해 존재합니다. 어떤 일회용 이메일 서비스가 내 메시지를 가지고 수상한 일을 하는 것은 아닌지 궁금하다면, 그 서비스에도 처리 과정을 공개해 달라고 요청해 보세요. PureTempMail은 방금 공개했습니다.
기술 용어 없이 짧게 정리된 설명을 보고 싶으신가요? PureTempMail 작동 방식 단계별로 보기