1. 지난 글에서 남은 질문
이전글에서 우리는 이런 질문으로 출발했다.
우리 서버가 직접 이메일을 보낼 수 있을까?
하지만 이 질문에 바로 답하려고 하면 조금 막막하다.
이메일을 “보낸다”는 말이 생각보다 넓기 때문이다. 사용자가 메일을 작성하는 것도 보내는 과정처럼 보이고, 우리 서버가 다른 서버에 전달하는 것도 보내는 과정처럼 보이고, 수신자가 메일함에서 읽는 것도 전체 흐름 안에 들어있다.
그래서 구현을 시작하기 전에 먼저 지도를 그려보려고 한다.
메일은 어디에서 출발해서 어디까지 가는 걸까?
메일은 어디에서 출발해서 어디까지 가는 걸까?
그리고 그중에서 SMTP는 정확히 어느 구간을 담당하는 걸까?
2. 이메일에는 여러 역할이 있다
처음에는 이메일 시스템이 단순하게 보인다.
보내는 사람 → 받는 사람
하지만 실제로는 그 사이에 여러 역할이 있다.

여기서 우리가 구현하려는 SMTP는 이 전체 과정 중에서도 메일을 전송하는 구간에 관여한다.
메일을 작성하는 화면도 아니고, 받은 메일을 읽는 기능도 아니다. SMTP는 메일을 어느 서버에서 다른 서버로 넘기는 쪽에 가깝다. RFC 5321도 SMTP를 메일 전송과 전달을 위한 프로토콜로 설명하고, 메일 읽기와 메시지 형식은 다른 문서와 프로토콜의 영역으로 구분한다.
3. SMTP에는 클라이언트와 서버가 있다
웹 개발을 하다 보면 보통 브라우저가 클라이언트고, API 서버가 서버라고 생각한다.
SMTP에서도 비슷하게 클라이언트와 서버가 있다. 다만 여기서 클라이언트는 꼭 사람이 사용하는 앱이 아닐 수 있다. 메일을 다른 서버로 보내려는 쪽이 SMTP 클라이언트가 되고, 메일을 받는 쪽이 SMTP 서버가 된다.
SMTP 클라이언트 ── 명령 ──> SMTP 서버
SMTP 클라이언트 <─ 응답 ─── SMTP 서버
즉, SMTP는 기본적으로 대화다.
클라이언트가 명령을 보내고, 서버가 응답한다. 클라이언트가 다시 명령을 보내고, 서버가 다시 응답한다.
이걸 조금 우체국처럼 생각해 보면, 보내는 쪽은 “이 편지를 이 사람에게 보내고 싶습니다”라고 말하고, 받는 쪽은 “좋습니다”, “그 주소는 모릅니다”, “본문을 보내세요” 같은 식으로 답하는 구조다.
4. 메일 서버는 하나의 역할만 하지 않는다
여기서 조금 헷갈리는 부분이 생긴다.
어떤 서버는 메일을 받을 때는 SMTP 서버다. 하지만 그 메일을 다시 다른 서버로 전달해야 한다면, 이번에는 SMTP 클라이언트가 된다.
즉, 하나의 서버가 상황에 따라 역할을 바꿀 수 있다.
A 서버 ──> B 서버 ──> C 서버
이 흐름에서 B 서버는 A에게 메일을 받을 때는 서버이고, C에게 메일을 보낼 때는 클라이언트다.
이런 중간 전달자를 릴레이라고 부를 수 있다. RFC 5321의 SMTP 모델도 SMTP 서버가 최종 목적지일 수도 있고, 중간 릴레이나 게이트웨이 역할을 할 수도 있다고 설명한다.
5. 그러면 우리는 무엇을 만들 것인가
우리는 우선 가장 작은 SMTP 실험실을 만들 것이다.
SMTP 클라이언트가 접속한다
서버가 인사한다
클라이언트가 명령을 보낸다
서버가 응답한다
메일 데이터를 받아서 저장한다
구현 후 곧바로 구글이나 네이버로 메일을 보내고 싶을 수 있지만 그렇게 하지 못할 것이다.
telnet smtp.gmail.com 25
실제 gmail과 통신을 진행해보면 알 수 있다.
Trying 172.217.221.109...
Connected to smtp.gmail.com.
Escape character is '^]'.
220 smtp.gmail.com ESMTP d2e1a72fcca58-83965645d74sm6572331b3a.1 - gsmtp
이건 gmail이 우리에게 보낸 것이다.
EHLO test.com
250-smtp.gmail.com at your service, [121.152.99.9]
250-SIZE 35882577
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8
내가 EHLO 라는 문구로 내가 누구인지 보내면 이후 250으로 시작하는 여러 줄을 통해 gmail 서버가 자신의 소개와 자신이 지원하는 기능들을 소개한다. 이러한 것은 추후 언급하겠지만 중요한 것은 gmail의 경우 STARTTLS라고 TLS 환경에서만 동작을 진행한다. 즉 우리가 SMTP를 만들었지만 gmail은 우리가 보내는 것을 거부할 가능성이 높다 그렇기 때문에 우리는 일단 작은 서버부터 만들고 이후에 생각을 해볼 것이다.
6. RFC는 어디에 쓰일까
SMTP는 오래된 프로토콜이다. 오래되었다는 말은 낡았다는 뜻이기도 하지만, 동시에 많은 시스템이 오랫동안 같은 약속을 지켜왔다는 뜻이기도 하다.
우리가 SMTP 서버를 직접 구현하려면 그 약속을 어느 정도 따라야 한다. 그 약속이 정리된 문서가 RFC다.
앞으로 구현을 하다가 “서버가 먼저 말해야 하나?”, “응답은 어떤 형식이어야 하나?”, “메일 본문은 어디서 끝나나?” 같은 질문이 생길 때마다 RFC를 펼쳐볼 것이다.
지금은 RFC를 처음부터 끝까지 읽지 않는다. 먼저 지도를 그리고, 길을 잃을 때마다 필요한 부분을 찾아본다.
자료 참조
https://datatracker.ietf.org/doc/html/rfc5321
RFC 5321: Simple Mail Transfer Protocol
This document is a specification of the basic protocol for Internet electronic mail transport. It consolidates, updates, and clarifies several previous documents, making all or parts of most of them obsolete. It covers the SMTP extension mechanisms and bes
datatracker.ietf.org
'Deep Dive > 기타' 카테고리의 다른 글
| [SMTP] 1. SMTP를 직접 구현해보기로 했다. (0) | 2026.05.07 |
|---|
