이 글의 위치: 기술 블로그 → 인프라 · 「쿠버네티스 SMTP」 시리즈의 사전 정리편(2).
앞선 글: Postfix·OpenSMTPD·Haraka·Mailu·Mailcow는 각각 무엇을 맡나
작성·검증 방식은 Editorial Policy 를 참고하세요.
"SMTP·IMAP·JMAP 지원"이 무슨 뜻인지 몰라서 막혔다
메일 서버 후보를 고르다가 Stalwart의 소개 문구에서 멈췄습니다.
an open-source mail & collaboration server with JMAP, IMAP4, POP3, SMTP, CalDAV, CardDAV and WebDAV support
여기서 저는 정직하게 막혔습니다. SMTP는 "메일 보내는 것"이라고 알고 있었지만, IMAP과 POP3의 차이를 설명해 보라고 하면 못 했을 것이고, JMAP은 처음 보는 이름이었습니다. 그리고 이 목록이 길다는 게 좋은 건지, 필요 없는 게 붙어 있는 건지도 판단이 안 섰습니다.
메일 클라이언트를 설정할 때 늘 보던 화면도 그제야 다시 보였습니다. "POP3/SMTP 설정"과 "IMAP/SMTP 설정" 중 하나를 고르라는 그 화면 말입니다. 양쪽 다 SMTP가 붙어 있고 앞부분만 다릅니다. 왜 그런지 설명할 수 있어야 서버도 고를 수 있겠다 싶었습니다.
결론부터 적으면 구도는 아주 단순합니다.
보내는 프로토콜은 하나(SMTP)뿐이고, 읽는 프로토콜이 셋(POP3·IMAP·JMAP)이다.
메일 클라이언트 설정에 SMTP가 항상 붙어 있는 이유가 이것입니다. 보내는 쪽은 선택지가 없어서 고정이고, 고르라는 건 읽는 방식입니다.
1. 보내기 — SMTP 하나뿐
SMTP(Simple Mail Transfer Protocol, RFC 5321)는 메일을 한 방향으로 밀어 넣는 프로토콜입니다. 1982년에 나온 규격이 아직도 인터넷 메일의 유일한 전송 수단입니다.
중요한 건 SMTP가 읽는 기능이 아예 없다는 점입니다. SMTP로는 "내 메일함에 뭐가 있나"를 물어볼 수 없습니다. 밀어 넣기만 합니다. 그래서 읽으려면 반드시 다른 프로토콜이 필요합니다.
SMTP는 쓰이는 자리에 따라 포트가 갈립니다. 이름은 같지만 성격이 다릅니다.
| 포트 | 이름 | 누가 쓰나 | 성격 |
|---|---|---|---|
| 25 | SMTP relay | 서버 ↔ 서버 | 남의 메일 서버가 내게 배달할 때. 인증 없음 |
| 587 | Submission (RFC 6409) | 사용자 → 자기 서버 | 로그인 필요. STARTTLS로 암호화 |
| 465 | Submission over TLS (RFC 8314) | 사용자 → 자기 서버 | 처음부터 TLS. 587의 대안 |
메일 클라이언트 설정에서 보내는 포트로 587이나 465를 넣는 이유가 여기 있습니다. 25번은 서버끼리 쓰는 문이라 클라이언트가 쓸 문이 아닙니다. 그리고 앞 글에서 다룬 "클라우드가 아웃바운드 25번을 막는다"는 문제도 정확히 이 서버↔서버 구간의 이야기입니다.
2. 읽기 — POP3, IMAP, JMAP
POP3 — 내려받고 서버에서 지운다
POP3(Post Office Protocol v3, RFC 1939, 포트 110 / 995)는 이름 그대로 우체통입니다. 접속해서 쌓인 메일을 전부 내려받고, 기본 동작은 서버에서 지우는 것입니다.
전제는 "메일을 읽는 기기가 하나"입니다. 1990년대에는 맞는 전제였습니다. 지금은 거의 항상 틀린 전제입니다. 폰에서 받으면 노트북에서 사라지니까요.
명령어가 열 몇 개뿐이라 서버 구현이 아주 단순합니다. 지금도 살아남은 이유는 그 단순함과, 오래된 장비·스캐너 같은 데서 아직 쓰기 때문입니다.
IMAP — 서버가 원본이고 클라이언트는 창문이다
IMAP4(Internet Message Access Protocol, RFC 3501 / rev2 RFC 9051, 포트 143 / 993)는 발상을 뒤집었습니다. 메일은 서버에 남아 있고, 클라이언트는 그것을 들여다봅니다.
그래서 IMAP은 POP3에 없는 것들을 서버에 둡니다.
- 폴더(메일박스) — 서버에 폴더를 만들고 옮기면 모든 기기에 반영
- 플래그 — 읽음·중요·답장함 상태를 서버가 기억
- 부분 조회 — 헤더만, 또는 첨부 뺀 본문만 먼저 받기
- 서버 검색 — 다 내려받지 않고 서버에 검색을 시킴
지금 쓰는 메일이 폰·노트북·웹에서 똑같이 보이는 건 IMAP(또는 그 이후 방식) 덕분입니다.
그래서 "POP3/SMTP"와 "IMAP/SMTP"의 차이
클라이언트 설정에서 고르라던 그 선택지가 실제로 무엇을 바꾸는지 정리하면 이렇습니다.
| POP3 + SMTP | IMAP + SMTP | |
|---|---|---|
| 메일 원본이 있는 곳 | 내 기기 | 서버 |
| 여러 기기에서 보기 | 사실상 안 됨 | 됨 |
| 읽음·별표 표시 동기화 | 안 됨 | 됨 |
| 폴더 구조 | 기기마다 따로 | 서버에 하나 |
| 한 기기에서 지우면 | 다른 기기에 영향 없음 | 모든 기기에서 사라짐 |
| 서버 저장 용량 | 거의 안 씀(내려받고 삭제) | 계속 씀 |
| 오프라인에서 보기 | 이미 받았으니 됨 | 캐시된 만큼 |
| 서버가 죽으면 | 받아 둔 건 남음 | 접근 불가 |
정리하면 POP3는 소유하고 IMAP은 동기화합니다. 지금 새로 만드는 시스템에서 POP3를 고를 이유는 거의 없고, 오래된 클라이언트 호환용으로 남겨 두는 정도입니다.
JMAP — IMAP을 HTTP/JSON으로 다시 쓴 것
JMAP(JSON Meta Application Protocol, RFC 8620 코어 / RFC 8621 메일)은 가장 최근에 표준이 된 방식입니다. 포트는 따로 없고 HTTPS(443) 위에서 JSON으로 오갑니다.
IMAP이 잘 작동하는데 왜 새로 만들었나. IMAP의 구조적 불편이 모바일에서 두드러졌기 때문입니다.
| IMAP의 불편 | JMAP의 대응 |
|---|---|
| 폴더마다 연결을 따로 열고 상태를 유지해야 함 | 상태 없는 HTTP 요청. 연결 유지 불필요 |
| 요청 한 번에 하나씩 — 왕복이 많아 모바일에서 느림 | 여러 작업을 한 요청에 묶어 전송 |
| "뭐가 바뀌었나"를 알려면 다시 훑어야 함 | 상태 토큰으로 바뀐 것만 받음 |
| 푸시 알림이 표준 밖(별도 연결 유지) | EventSource·WebSocket 푸시가 규격 안에 |
| 텍스트 명령이라 파서마다 해석이 다름 | JSON — 흔한 도구로 그대로 다룸 |
한 줄로 줄이면 JMAP은 "모바일과 웹을 전제로 다시 쓴 IMAP" 입니다. HTTP 위라서 기존 로드밸런서·프록시·인증 인프라를 그대로 쓸 수 있다는 점도 서버 운영자에게는 큽니다.
다만 현실적인 제약이 하나 있습니다. JMAP을 지원하는 메일 클라이언트가 아직 적습니다. 서버가 JMAP을 지원해도 Outlook·Thunderbird·iOS 기본 메일이 IMAP으로 붙는 경우가 대부분이라, 당분간은 IMAP도 같이 열어 두어야 합니다. 그래서 Stalwart 같은 서버가 JMAP과 IMAP을 동시에 지원하는 것이지, JMAP만 있으면 되는 상황이 아닙니다.
3. 메일 한 통이 지나가는 길과, 프로토콜이 붙는 자리
지금까지의 이름들을 한 그림에 놓으면 이렇습니다.
[보내는 사람] [받는 사람]
메일 클라이언트 메일 클라이언트
│ ▲ ▲ ▲
│ SMTP Submission │ │ │
│ (587 / 465, 로그인 필요) POP3 │ │ │ JMAP
▼ (110/995)│ │ (HTTPS 443)
┌───────────────┐ SMTP relay ┌──────────────┴───┴──────┐
│ 보내는 쪽 MTA │ ─────────────────────▶ │ 받는 쪽 서버 │
│ (큐·재시도) │ (25번 포트) │ MTA + 메일함(스토어) │
└───────────────┘ └─────────────────────────┘
▲ ▲
│ │ IMAP (143/993)
LMTP·Sieve로
최종 배달·분류
- 왼쪽 절반이 SMTP의 세계입니다. 보내고, 큐에 쌓고, 재시도하고, 남의 서버에 밀어 넣습니다.
- 오른쪽 절반이 메일함의 세계입니다. 저장하고, 폴더를 관리하고, 클라이언트가 읽어 갑니다.
- 이 두 절반은 완전히 다른 일입니다. 그래서 앞 글에서 본 것처럼 Postfix(MTA)와 Dovecot(메일함)이 따로 존재합니다.
그리고 이 그림이 서버 선택에서 결정적입니다. 오른쪽 절반이 없는 제품이 있습니다. 뒤에서 다시 이야기하겠습니다.
4. 그 외에 알아 둘 만한 프로토콜들
이름이 나올 때 당황하지 않을 정도로만 정리해 둡니다.
메일함 주변
| 이름 | 하는 일 |
|---|---|
| Sieve (RFC 5228) | 서버 측 메일 분류 규칙 언어. "제목에 X가 있으면 이 폴더로" 를 서버가 수행 |
| ManageSieve (RFC 5804, 4190) | 그 Sieve 스크립트를 클라이언트가 올리고 고치는 프로토콜 |
| LMTP (RFC 2033) | MTA가 로컬 메일함에 최종 배달할 때 쓰는 SMTP 사촌. 수신자별로 성공/실패를 따로 답함 |
| milter | 메일이 큐를 지나는 중간에 필터(스팸·DKIM)를 끼우는 인터페이스. Postfix·Sendmail 계열 |
Sieve가 왜 중요한가 하면, 클라이언트를 안 켜도 분류가 된다는 점 때문입니다. 클라이언트 필터는 그 앱이 떠 있어야 돌지만 Sieve는 서버가 배달하는 순간 적용됩니다.
협업(메일이 아닌 것들)
| 이름 | 하는 일 |
|---|---|
| CalDAV (RFC 4791) | 일정 동기화 |
| CardDAV (RFC 6352) | 주소록 동기화 |
| WebDAV (RFC 4918) | 파일 저장·공유 |
| Exchange ActiveSync / MAPI | 마이크로소프트 계열 독자 규격. 오픈소스 구현은 드묾 |
Stalwart 소개에 CalDAV·CardDAV·WebDAV가 붙어 있는 건 메일 서버를 넘어 그룹웨어까지 하겠다는 뜻입니다. 제 목표는 메일(SMTP+메일함)까지라, 이 셋은 당장은 쓰지 않고 열어 두지도 않을 생각입니다.
인증·보안 (프로토콜이라기보다 규칙)
이 계열은 "메일을 주고받는 방법"이 아니라 "이 메일이 진짜인지, 연결이 안전한지" 를 다룹니다. 자체 발송을 하려면 피할 수 없는 목록입니다.
| 이름 | 한 줄 |
|---|---|
| SPF (RFC 7208) | 이 도메인의 메일을 보낼 수 있는 IP 목록을 DNS에 공개 |
| DKIM (RFC 6376) | 메일에 전자서명을 붙이고 공개키를 DNS에 둠 |
| DMARC (RFC 7489) | SPF·DKIM이 실패하면 어떻게 할지(격리·거부)와 리포트 받을 주소를 선언 |
| ARC (RFC 8617) | 메일링리스트처럼 중간에서 변형될 때 원래 인증 결과를 이어 붙임 |
| DANE (RFC 6698) | DNSSEC로 상대 서버의 TLS 인증서를 검증 |
| MTA-STS (RFC 8461) | DANE의 대안. HTTPS로 정책을 공개해 TLS 강제 |
| TLS-RPT (RFC 8460) | TLS 연결 실패를 상대가 리포트로 알려 줌 |
앞의 셋(SPF·DKIM·DMARC)은 선택이 아니라 필수입니다. 이게 없으면 보낸 메일이 스팸함으로 갑니다.
5. 이 목록이 서버 선택에서 결정하는 것
여기까지 정리하고 나서 후보들을 다시 보니, 문장 하나가 완전히 다르게 읽혔습니다.
| 제품 | SMTP | POP3 | IMAP | JMAP | 그래서 |
|---|---|---|---|---|---|
| Postal | ✅ | ❌ | ❌ | ❌ | 메일함이 없다 — 앱 발송 전용 |
| Stalwart | ✅ | ✅ | ✅ | ✅ | 메일 서버 전체 |
| Postfix + Dovecot | ✅ | ✅ | ✅ | ❌ | 고전 조합. JMAP은 없음 |
| Mailu / Mailcow | ✅ | ✅ | ✅ | ❌ | 위 조합을 묶은 배포판 |
| Mox (Go) | ✅ | ❌ | ✅ | ❌ | POP3·JMAP은 로드맵 |
Postal의 공식 기능 목록을 다시 읽어 봤는데 IMAP·POP3·JMAP이 단 한 번도 나오지 않습니다. 수신 메일 처리 항목은 이렇게만 되어 있습니다.
들어온 메일을 HTTP 엔드포인트로 전달 / 다른 SMTP 서버로 전달 / 다른 메일 주소로 전달
즉 Postal은 앞의 그림에서 왼쪽 절반만 있는 제품입니다. 메일을 보관하고 클라이언트가 읽어 가는 오른쪽 절반이 아예 없습니다. 이건 Postal이 부족해서가 아니라 의도된 범위입니다. 스스로를 "Sendgrid·Mailgun·Postmark 같은 것"이라고 소개하는데, 그 서비스들도 메일함을 주지 않습니다.
그래서 선택의 첫 질문은 "어느 게 더 좋은가"가 아니었습니다.
사람이 로그인해서 읽는 메일함이 필요한가, 아니면 앱이 보내기만 하면 되는가.
여기서 갈리면 나머지는 자동으로 정해집니다. 그리고 저는 메일함이 필요한 쪽으로 정했습니다. 예전에 "보내기"만 만들었다가 스팸함으로 갔던 아쉬움이 있어서, 이번엔 보내는 쪽과 받아서 보관하는 쪽을 모두 갖춘 형태로 만들어 보려고 합니다. 그 순간 Postal은 후보에서 빠집니다 — 부족해서가 아니라 애초에 발송 전용 제품이기 때문입니다.
6. 정리
- 보내는 프로토콜은 SMTP 하나뿐이고 읽는 프로토콜이 셋입니다. 클라이언트 설정에 SMTP가 늘 붙어 있는 이유입니다.
- SMTP는 자리에 따라 포트가 다릅니다. 25는 서버끼리, 587·465는 사용자가 자기 서버로. 클라우드가 막는 건 25번입니다.
- POP3는 소유(내려받고 삭제), IMAP은 동기화(서버가 원본) 입니다. 한 기기에서 지우면 전부 사라지는 게 IMAP의 정상 동작입니다.
- JMAP은 IMAP을 HTTP/JSON으로 다시 쓴 것입니다. 다만 클라이언트 지원이 아직 적어 IMAP을 대체하기보다 함께 여는 단계입니다.
- Sieve(서버 측 분류)·LMTP(로컬 최종 배달)·milter(중간 필터)는 메일함 주변, CalDAV·CardDAV는 그룹웨어 영역입니다.
- SPF·DKIM·DMARC는 선택이 아니라 필수입니다.
- 그리고 가장 중요한 것 — Postal에는 메일함이 없습니다. 이게 Postal과 Stalwart를 가르는 진짜 기준입니다.
이 기준으로 두 후보를 다시 비교한 내용은 다음 글에 있습니다 → Postal이냐 Stalwart냐 — 메일함까지 만들기로 하니 답이 좁혀졌다
함께 읽으면 좋은 글:
- [메일 인프라] Postfix·OpenSMTPD·Haraka·Mailu·Mailcow는 각각 무엇을 맡나 — MTA와 메일함이 왜 다른 소프트웨어인지
- [로컬 서버 운영기] 한 번 로그인으로 다 쓰기 — Keycloak SSO — 메일 계정 인증을 OIDC·LDAP으로 붙일 때의 배경
참고 (1차 출처)
- SMTP RFC 5321 · Submission RFC 6409 · RFC 8314
- POP3 RFC 1939 · IMAP4rev1 RFC 3501 · IMAP4rev2 RFC 9051
- JMAP RFC 8620 · JMAP for Mail RFC 8621
- Sieve RFC 5228 · ManageSieve RFC 5804 · LMTP RFC 2033
- SPF RFC 7208 · DKIM RFC 6376 · DMARC RFC 7489 · MTA-STS RFC 8461
- Postal 기능 목록 · Stalwart README · Mox README
답글 남기기