Operation/Network

메일 서비스 작동 원리 (with 구글, 네이버 등)

JaeHoney 2022. 3. 5. 11:53

메일 작동 원리

메일을 전송하고 전송 받을 때 사용하는 프로토콜은 크게 3가지로 나눌 수 있습니다.

SMTP: 메일을 송신할 때 사용하는 프로토콜

  • TCP/IP 호스트 사이의 메일을 전달할 때 사용됨

POP3: 메일을 전송받을 때 사용하는 프로토콜

  • POP3는 로컬에서 수정, 삭제를 해도 메일 서버에는 변화가 없음.
  • 메일을 수신할 때는 주로 POP3, IMAP을 사용.

IMAP: 메일을 전송받을 때 사용되는 또 하나의 프로토콜

  • IMAP은 POP3의 단점의 비동기성을 보완하기 위한 방식
  • 각 로컬마다 데이터가 다르지 않고 어떤 디바이스에서 메일을 열든 동일하게 동기화하는 방식
  • 복잡하다는 단점이 있음.

기본 메일 서버의 동작 구조는 아래와 같습니다.

<예시 시나리오>

  1. abc@abc.com 사용자가 메일서버에게 MUA(Mail user agent ex:gmail)로 작성된 편지를 SMTP를 이용하여 발송 (메일 내용에는 도착지(def@d ef.com) 의 정보가 들어있음)
  2. 메일서버 A(abc.com)는 25번 포트(SMTP)로 메일을 수신함
  3. 메일서버 A(abc.com)는 도착지 서버 B(def.com)의 MX 레코드를 DNS 서버에서 요청해서 가져옴
  4. 메일서버 A(abc.com)는 MX레코드로 도착지 메일서버 B(def.com)의 IP주소를 가져옴
  5. 메일서버 A(abc.com)은 받은 메일을 메일서버 B(def.com)로 메일을 다시 전송함.
  6. 메일서버 B(def.com)는 MDA(Mail delivery agent)를 통해 수신자(def@def.com)의 메일박스에 메일을 적재함
  7. def@def.com 사용자는 POP 또는 IMAP 프로토콜로 메일을 가져옴

해당 동작은 정석적인 메일 서버의 절차입니다. Outlook을 사용할 때는 위와 같이 동작하는게 맞습니다. 네이버 메일, 다음 메일, 구글 메일 등은 위와 조금 다릅니다. 수신을 POP3 / IMAP으로 하지 않습니다.

  • 메일서버는 수신한 메일의 meta-data를 DB에 보관하고 서버를 배포
  • 수신자는 서버에 HTTP로 접근해서 메일 정보를 읽음

일반적으로 메일을 접속한 후 설정을 들어가보면 POP3/IMAP 사용하기 라는 체크란이 있고, 기본으로는 사용하지 않게 되어 있습니다. 위에 언급했듯, 보통 HTTP를 이용해서 사용하기 때문입니다.

단, 외부 메일을 가져올 때는 POP3를 사용합니다. 예를 들어, 구글메일에서 네이버 계정에 있는 메일을 가져올 수 있습니다. 이럴 때는 POP3를 사용해서 대량으로 가져옵니다.

MX 레코드

시나리오 3번에서 "메일서버 A(abc.com)는 도착지 서버 B(def.com)의 MX 레코드를 DNS 서버에서 요청해서 가져옴" 이라고 소개해드렸습니다.

MX 레코드는 메일 서버의 주소를 알려주는 역할을 합니다

(ex. naver.com는 도메인이고, 223.130.200.107은 네이버의 ip주소. 네이버의 MX레코드를 이용해서 mail.naver.com의 IP주소 를 가져올 수 있음.)

MX 레코드는 다음과 같이 조회할 수 있습니다.

nslookup -query=mx domainname

그럼 아래와 같은 결과가 출력됩니다.

naver.com 도메인에서는 메일 서버를 3개를 사용하고 있고, 우선 순위는 전부 10으로 동일하다는 의미입니다. 각 메일 서버의 도메인도 알 수 있습니다.

MX레코드를 이용하면 도착지의 메일 서버 도메인을 알 수 있고, 도메인을 이용해서 IP 주소를 얻을 수 있습니다.

.EML 파일

메일은 .eml의 확장자를 가진 파일로 전송됩니다. EML파일의 구조는 아래와 같습니다. 메일 서비스 제공자(네이버 메일, 구글 메일 등)는 이 EML파일을 읽어서 해석(Parsing)한 후, 사용자가 보기 좋게 UI를 통해 보여줍니다.

Return-Path: <sas@naver.com>
Delivered-To: safdsfsdf@gmail.com
Received: (hhosting 18061 invoked from network); 28 Apr 2021 11:58:18 +0900(KST)
Received: from localhost.localdomain (dev-web [127.0.0.1])         by localhost.localdomain (8.15.2/8.13.8)
with ESMTP id 13S2wHeg006680         for <safdsfsdf@test-jerry.com>; Wed, 28 Apr 2021 11:58:17 +0900
Received: (from nobody@localhost)         by localhost.localdomain (8.15.2/8.13.8/Submit) id
13S2wHdp006679;         Wed, 28 Apr 2021 11:58:17 +0900
X-Authentication-Warning: localhost.localdomain: nobody set sender to sxa@naver.com using -f
Date: Wed, 28 Apr 2021 11:58:17 +0900
From: =?utf-8?B?YWRhZmRAdGVzc3NzLmNvbQ==?= <jerryemail@test-jerry.com>
To: safdsfsdf@test-jerry.com
Reply-To: =?utf-8?B?ImFkYWZkQHRlc3Nzcy5jb20i?= <jerryemail@test-jerry.com>
Subject: =?utf-8?B?dGVzdA==?=
X-Sender: jerryemail@test-jerry.com
X-Mailer: Mail
X-Priority: 3 (Normal)
Message-ID: <gab6088cf49aefa3@test-jerry.com>@domain@jerryemail@test-jerry.com
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary="B_ALT_6088cf49af009"
This is a multi-part message in MIME format.
Your email application may not support this format.
--B_ALT_6088cf49af009
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64
dGVzdAo=
--B_ALT_6088cf49af009
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable
<html><head><style>P{font-size:9px; line-height:1.6em;  margin-left:0; marg=
in-top:0; margin-right:0; margin-bottom:0; font-family:=EB=B0=94=ED=83=95=
=EC=B2=B4;}</style></head><body><div style=3D"font-size:9p=
x; line-height:1.6em;margin:0px 0px 0px 0px;" ><p style=3D"font-si=ze: 10px; line-height: 1.6; margin-top: 0px; margin-bottom: 0px;">test</p><=
/div></body></html>
--B_ALT_6088cf49af009--

 

EML은 MIME RFC 822에서 표준으로 하는 전자 메일 메시지의 형식입니다. RFC 822 형식은 Binary를 사용하지 않고 헤더까지 ASCII로 작성하기 때문에 이해하기 쉽습니다.

헤더는 여러개 정의할 수 있고 순서를 각각 다르게 할 수 있는 유연성이 있습니다.

실습

공부한 내용을 실습할 때는 사용하시는 메일서버를 사용하면 됩니다. 터미널을 열고 아래의 문장을 순서대로 입력합니다.

1. Telnet [mailserver] 25
2. helo [mailserver]
3. mail from: ti6419@gmail.com
4. rcpt to: ti6419@gmail.com
5. data
6. subject: Main
7. from: from123@co.kr
8. to: to123@co.kr
9. text~~~
10. .
11. quit

위 내용을 정리하면 다음과 같습니다.

  1. telnet을 사용해서 메일서버에 연결합니다. telnet은 TCP/IP 기반으로 특정 주소의 포트에 원격 접속할 수 있는 프로토콜입니다.
  2. 메일 서버에 메일 보내기를 시작합니다.
  3. 송신자를 입력합니다.
  4. 수신자를 입력합니다.
  5. meta-data 입력을 끝내고 data 입력을 시작합니다.
  6. 메일 제목을 설정합니다.
  7. 보일 송신자를 입력합니다. (아무렇게나 입력해도 상관없습니다.)
  8. 보일 수신자를 입력합니다.
  9. 메일 본문을 입력합니다.
  10. 메일 내용 입력을 마치겠다는 뜻에서 .을 입력합니다.
  11. quit를 사용해서 커넥션을 끊습니다.
  12. 개발용 서버에 접속해보면, 메일이 온 것을 확인할 수 있습니다.

meta-data가 아닌 data에서의 from과 to는 실제 동작과는 무관하게 표시할 때 사용하는 데이터입니다. 해당 데이터가 잘못되어도 문제는 없지만 메일 서비스 제공자는 자체적으로 사칭위험 경고를 제공합니다.

감사합니다.