컴퓨터 네트워킹(하향식 접근) - 02 애플리케이션 계층(3/7)

최준석·2022년 12월 11일
0

애플리케이션 계층

2.3 인터넷 전자메일

전자메일은 인터넷이 시작된 이래로 널리 확산되었다. 이것은 인터넷 초창기에 매우 인기 있는 애플리케이션이었으며, 해가 지날수록 더욱 정교하고 강력해졌다. 이것은 오늘날 인터넷의 가장 중요하고 널리 사용되는 애플리케이션 중 하나다.

일반 우편과 마찬가지로 전자메일은 비동기적인 통신 매체다. 일반 우편과는 다르게 전자메일은 분배가 쉽고, 빠르고 저렴하다. 현대의 전자메일은 첨부된 메시지, 하이퍼링크, HTML 포맷 텍스트, 내장된 사진 등 많은 강력한 특성을 지니고 있다.

이 절에서는 인터넷 인터넷 전자메일 구조의 중심에 있는 애플리케이션 계층 프로토콜을 알아본다.

위 그림은 인터넷 메일 시스템의 상위 레벨 개념을 보여준다. 이 다이어그램에 사용자 에이전트(user agent), 메일 서버(mail server), SMTP(Simple Mail Transfer Protocol) 라는 3개의 주요 요소가 있음을 알 수 있다. 이제 각 요소들을 송신자 앨리스가 수신자 밥에게 전자메일을 보내는 상황에서 기술한다. 사용자 에이전트는 사용자가 메시지를 읽고, 응답하고, 전달하고, 구성하게 해준다. 전자메일을 위한 대표적인 사용자 에이전트에는 마이크로소프트 아웃룩, 애플 메일, 웹 기반 지메일 스마트폰용 지메일 앱 등이 있다. 앨리스가 메시지 작성을 끝내면, 사용자 에이전트는 메시지를 메일 서버로 보내고, 거기서 메시지는 메일 서버의 출력 메시지 큐에 들어간다. 밥이 메시지를 읽고 싶을 때 그의 사용자 에이전트는 메일 서버에 있는 메일박스에서 메시지를 가져온다.

메일 서버는 전자메일 인프라스트럭처의 중심이다. 밥 같은 각 수신자는 메일 서버 안에 메일박스(mailbox) 를 갖고있다. 밥의 메일박스는 그에게 온 메시지를 유지하고 관리한다. 일반 메시지는 송신자의 사용자 에이전트에서 전달이 시작되고, 송신자의 메일 서버를 거친 후에 수신자의 메일 서버로 전달된다. 거기서 수신자의 메일박스에 저장된다. 밥이 전자메일 박스에 있는 메시지를 보려면, 메일 서버는 사용자 게정과 비밀번호를 이용하여 밥을 인증한다. 앨리스의 메일 서버는 밥의 메일 서버 고정에도 대처해야 한다. 앨리스 서버가 메일을 밥의 서버로 전달할 수 없다면, 앨리스 서버는 그 메시지를 메시지 큐(message queue) 에 보관하고 나중에 그 메시지를 전달하기 위해 다시 시도한다. 재시도는 약 30분마다 일어난다. 여러 날 시도해도 성공하지 못하면, 서버는 그 메시지를 제거하고 송신자(앨리스)에게 전자메일로 이를 통보한다.

SMTP는 인터넷 전자메일을 위한 주요 애플리케이션 계층 프로토콜이다. SMTP는 메일을 송신자의 메일 서버로부터 수신자의 메일 서버로 전송하는 데 TCP의 신뢰적인 데이터 전송 서비스를 이용한다. 대부분의 애플리케이션 계층 프로토콜처럼, SMTP는 송신자 메일 서버에서 수행하는 클라이언트와 수신자 메일 서버에서 수행되는 서버를 갖고있다. SMTP의 클라이언트와 서버 모두가 모든 메일 서버에서 수행된다. 메일 서버가 상대 메일 서버로 메일을 보낼 때는 SMTP의 클라이언트로 동작하는 반면, 메일 서버가 상대 메일 서버로부터 메일을 받을 때는 SMTP 서버로 동작한다.

2.3.1 SMTP

RFC 5321에 정의된 SMTP는 인터넷 전자메일의 중심에 있다. 앞에서 언급한 대로, SMTP는 송신자의 메일 서버로부터 수신자의 메일 서버로 메시지를 전송한다. SMTP는 HTTP보다 훨씬 오래되었다(SMTP RFC는 1982년에 만들어졌고 SMTP는 훨씬 이전부터 있었다). SMTP는 여러 가지 장점이 있지만, 낡은 특성을 가진 오래된 기술이다. 예를 들어, 모든 메일 메시지의 몸체(헤더뿐 아니라)는 단순한 7비트 ASCII여야 한다는 단점이 있다. 이 제한은 전송용량이 제한되고 커다란 첨부파일이나 커다란 이미지, 오디오 혹은 비디오 파일을 보내지 않았던 1980년대 초에는 나름대로 의미가 있었다. 그러나 오늘날의 멀티미디어 시대에서 7비트 ASCII 제한은 문제를 일으킨다. SMTP를 통해 이진 멀티미디어 데이터를 보내기 전에 ASCII로 변환할 필요가 생겼다. 그리고 SMTP 전송 후에는 ASCII를 다시 원래 메시지로 변환해야만 한다. 2.2절에서 살펴봤듯이 HTTP는 전송 전에 멀티미디어 데이터를 ASCII로 변환하는 것을 요구하지 않는다.

SMTP의 기본 동작을 설명하기 위해 일반 시나리오를 살펴보자. 앨리스가 간단한 ASCII 메시지를 밥에게 보낸다고 가정하자.

  1. 앨리스는 전자메일 사용자 에이전트를 수행하고 밥의 전자메일 주소(예:bob@someschool.edu)를 제공하고, 메시지를 작성하고 사용자 에이전트에게 메시지를 보내라고 명령한다.
  2. 앨리스의 사용자 에이전트는 메시지를 그녀의 메일 서버에게 보내고 그곳에서 메시지는 메시지 큐에 놓인다.
  3. 앨리스의 메일 서버에서 동작하는 SMTP의 클라이언트 측은 메시지 큐에 있는 메시지를 본다. 밥의 메일 서버에서 수행되고 있는 SMTP 서버에게 TCP 연결을 설정한다.
  4. 초기 SMTP 핸드셰이킹 이후에 SMTP 클라이언트는 앨리스의 메시지를 TCP 연결로 보낸다.
  5. 밥의 메일 서버 호스트에서 SMTP의 서버 측은 메시지를 수신한다. 밥의 메일서버는 그 메시지를 밥의 메일박스에 놓는다.
  6. 밥은 편한 시간에 그 메시지를 읽기 위해 사용자 에이전트를 시동한다.

이 시나리오는 다음 그림에 요약되어 있다.

SMTP는 메일을 보낼 때 두 메일 서버가 먼 거리에 떨어져 있더라도 중간 메일 서버를 사용하지 않음을 이해하는 것이 중요하다. 앨리스의 서버가 홍콩에 있고 밥의 서버가 세인트루이스에 있다면, TCP 연결을 홍콩과 세인트루이스 서버 사이의 직접 연결이다. 특히, 밥의 메일 서버가 죽어 있다면 메시지는 어느 중간 메일 서버에 저장되는 것이 아니라 앨리스의 메일 서버에 남아 새로운 시도를 위해 기다린다.

이제 SMTP가 메시지를 송신 메일 서버에서 수신 메일 서버로 어떻게 전송하는지 자세히 살펴보자. SMTP 프로토콜이 마주본(face-to-face) 사람의 상호작용에 이용되는 프로토콜과 유사함을 알게 될 것이다. 첫째, 클라이언트 SMTP(송신 메일 서버 호스트에서 수행된다)는 서버 SMTP(수신 메일 서버 호스트에서 수행된다)의 25번 포트로 TCP 연결을 설정한다. 만약 서버가 죽어 있으면 클라이언트는 나중에 다시 시도한다. 일단 이 연결이 설정되면, 서버와 클라이언트는 애플리케이션 계층 핸드세이킹을 수행한다. 사람들이 정보를 전달하기 전에 서로 소개하는 것처럼, SMTP 클라이언트와 서버는 정보를 전송하기 전에 서로 소개한다. 이 SMTP 핸드세이킹 과정 동안에 SMTP 클라이언트는 송신자의 전자메일 주소와 수신자의 전자메일 주소를 제공한다. 일단 SMTP 클라이언트와 서버가 서로에 대한 소개를 마치면, 클라이언트는 메시지를 보낸다. SMTP는 서버에 오류 없이 메시지를 전달하기 위해 TCP의 신뢰적인 데이터 전송 서비스에 의존한다. 그리고 서버에 보낼 다른 메시지가 있으면, 클라이언트는 이 과정을 같은 TCP 연결상에서 반복한다. 그렇지 않으면 TCP에게 연결을 닫을 것을 명령한다.

SMTP 클라이언트(C)와 SMTP 서버(S) 사이의 메시지 전달 과정의 예를 살펴보자. 클라이언트의 호스트 이름은 crepes.fr이고 서버의 호스트 이름은 hamburger.edu다. C: 다음에 나오는 ASCII 텍스트 라인은 클라이언트가 TCP 소켓으로 보내는 라인이다. S: 다음에 나오는 ASCII 텍스트 라인은 서버가 TCP 소켓으로 보내는 라인이다. 다음 내용은 TCP 연결이 설정되자마자 시작된다.

S: 220 hanburger.edu
C: HELO crepes.fr
S: 250 Hello crepes.fr, pleased to meet you
C: MAIL FORM: < alice@crepes.fr >
S: 250 alice@crepes.fr ... Sender ok
C: RCPT TO: < bob@hamburger.edu >
S: 250 bob@bamburger.edu ... Recipient ok
C: DATA
S: 354 Enter mail, end with "." on a line by itself
C: Do you like ketchup
C: How about pickles?
C: .
S: 250 Message accepted for delivery
C: QUIT
S: 221 hamburger.edu closing connection

이 에에서 클라이언트는 메일 서버 crepes.fr로부터 메일 서버 hamburger.edu에게 "Do you like ketchup? How about pickles?" 메시지를 보낸다. 클라이언트는 5개의 명령, 즉 HELO(HELLO의 약자), MAIL FROM, RCPT TO, DATA, QUIT 명령을 내렸다. 또한 클라이언트는 하나의 점(.)으로 된 라인을 송신하며, 그것은 서버에게 메시지의 끝을 나타낸다(ASCII에서 각 메시지는 CRLF.CRLF로 끝나며, CR과 LF는 각각 'carriage return'과 'line feed'의 약자다). 서버는 각 명령에 응답하며, 각 응답에는 응답코드와 영문 설명(옵션)이 있다. SMTP는 지속(persistent) 연결을 사용한다는 것을 언급하고자 한다. 송신 메일 서버가 같은 수신 메일 서버로 보내는 여러 메시지를 갖고 있다면, 같은 TCP 연결을 통해 모든 메시지를 전달할 수 있다. 각 메시지에 대해 클라이언트는 새로운 MAIL FROM: crepes.fr로 과정을 시작하고 모든 메시지를 전송한 후에 QUIT를 보낸다.

텔넷을 사용하여 SMTP 서버와 직접 대화해보기 바란다. 이를 위해 다음 명령을 사용하라.

telnet serverName 25

여기서 serverName은 원격 메일 서버의 이름이다. 이 명령을 실행하면, 여러분의 로컬 호스트와 메일 서버 사이에 TCP 연결이 설정된다. 다음에는 즉시 서버로부터 220 응답을 받을 것이다. 그리고 SMTP 명령인 HELO, MAIL FROM, RCPT TO, DATA, CRLF.CRLF, QUIT를 적당한 때에 이용하면 된다.

2.3.2 메일 메시지 포맷

앨리스가 밥에게 일반 우편을 보낼 때는 편지를 우편봉투에 넣는데, 우편봉투에는 밥의 주소, 앨리스의 반송주소, 날짜 등 여러 가지 주변 정보가 적힌다. 마찬가지로, 전자메일을 보낼 때도 주변 정보가 포함된 헤더가 메시지 몸체 앞에 오게 된다. 이 주변 정보는 일련의 헤더 라인에 포함되는데 RFC 5322에 정의되어 있다. 헤더 라인과 메시지 몸체는 빈 줄(CRLF)로 분리된다. RFC5322는 메일 헤더 라인에 대한 정확한 포맷과 그 의미에 대한 해석을 기술하고 있다. HTTP에서처럼 각 헤더 라인은 키워드, 콜론, 값의 순서로 구성되고 읽을 수 있는 텍스트를 포함한다. 키워드 중 반드시 필요한 것도 있고 선택사항도 있다. 모든 헤더는 From: 헤더라인과 To: 헤더 라인을 반드시 가져야 한다. 헤더는 Subject: 헤더와 다른 옵션 헤더 라인을 가질 수도 있다. 이러한 헤더 라인들은 2.3.1절에서 배운 SMTP 명령과는 (비록 'from'과 'to'처럼 공통 단어가 있기는 하지만) 다름에 유의하라. 2.3.1절에 있는 명령은 SMTP 핸드셰이킹 프로토콜의 일부이고, 이 절에서 살펴본 헤더 라인들은 메일 메시지 자체의 일부다.

일반 메시지 헤더는 다음과 같다.

From: alice@crepes.fr
To: bob@hamburger.edu
Subject: Searching for the meaning of life.

메시지 헤더 다음에 빈 줄이 이어지고, 그 다음에 메시지 몸체(ASCII 문자)가 나온다. Subject: 헤더 라인을 비롯한 여러 헤더 라인을 포함하는 메시지를 메일서버로 보내도록 텔넷을 사용해보자. 이를 위해 2.3.1절에서 논의한 것처럼 telnet serverName 25를 입력한다.

2.3.3 메일 접속 프로토콜

SMTP가 앨리스의 메일 서버로부터 밥의 메일 서버로 메시지를 전달하고 나면, 메시지는 밥의 메일박스에 놓이게 된다. 밥(수신자)이 자신의 호스트(스마트폰이나 PC)에서 사용자 에이전트를 수행한다면, 메일 서버도 자신의 로컬 PC에 놓는 것이 자연스러울 것이다. 그러나 이 방식에는 문제가 있다. 메일 서버가 메일박스를 관리하고 SMTP의 클라이언트와 서버 측 모두를 수행한다는 것을 기억하라. 만약 밥의 메일 서버가 로컬 호스트에 있다면, 밥의 호스트는 언제든 도착할 수 있는 전자메일을 수신하기 위해 항상 켜져 있어야 하고 인터넷에 연결되어 있어야 한다. 이는 대부분의 인터넷 사용자에게 비현실적이다. 대신에 일반 사용자는 로컬 호스트에서 사용자 에이전트를 수행하고 늘 켜져 있는 공유 메일 서버에 저장된 메일박스에 접근한다. 메일 서버는 보통 사용자들과 공유한다.

이제 전자메일 메시지가 앨리스 사용자 에이전트로부터 밥 메일 서버로 전송될 때 전자메일 메시지가 갖는 경로를 생각해보자. 우리는 전자메일 메시지 경로를 따라 몇 가지 요소가 밥의 전자메일 서버에 보내져야만 한다는 것을 배웠다. 이것은 앨리스의 사용자 에이전트가 밥의 메일 서버에 직접 메시지를 보냄으로써 간단하게 수행될 수 있다. 그러나 앨리스의 사용자 에이전트는 밥의 메일 서버로 직접 대화하지 않는다. 대신에 다음 그림처럼 앨리스의 사용자 에이전트는 그녀의 메일 서버로 전자메일 메시지는 SMTP 또는 HTTP를 이용하여 보낸다.

그리고 앨리스의 메일 서버는 SMTP(클라이언트 SMTP)를 사용하여 밥의 메일 서버로 전자메일 메시지를 중계한다. 왜 둔 단계의 절차일까? 주요 이유는 앨리스의 메일 서버를 통해 중계하지 않으면 앨리스의 사용자 에이전트는 목적지 메일 서버에 도달할 수 없기 때문이다. 앨리스는 전자메일을 자신의 메일 서버에 먼저 저장하고 앨리스의 메일 서버는 그 메시지를 바의 메일 서버로 30분마다(밥의 메일 서버가 동작될 때까지) 반복해서 보내려고 한다.

그러나 아직도 이 문제에서 고려되지 않은 한 가지가 있다. 로컬 호스트 PC에서 사용자 에이전트를 수행하는 밥과 같은 수신자는 자신의 ISP 내부의 메일 서버에 있는 자신의 메시지를 어떻게 얻을 수 있는가? 밥의 사용자 에이전트는 메시지를 얻기 위해 SMTP를 사용할 수 없음을 주목하라. 이는 SMTP가 푸시(push) 프로토콜인 반면에 메시지를 얻는 것은 풀(pull) 동작이기 때문이다.

현재 밥이 메일 서버로부터 자신의 전자메일을 확인하는 대표적인 방법은 두 가지가 있다. 만일 밥이 웹 기반 전자메일이나 지메일 같은 스마트폰 앱을 사용하고 있다면 사용자 에이전트는 밥의 전자메일을 확인하기 위해 HTTP를 사용할 것이다. 이 경우에 밥의 메일 서버는 앨리스 메일 서버와 통신하기 위해 SMTP 인터페이스는 물론이고 HTTP 인터페이스를 갖고 있어야 한다. 다른 방법으로는 마이크로 소프트 아웃룩과 같은 전형적인 메일 클라이언트를 사용하는데, RFC 3501에 정의된 인터넷 메일 접근 프로토콜(Internet Mail Access protocol, IMAP) 을 사용하게 된다. HTTP나 IMAP 사용 방법 모두 밥의 메일 서버에 의해 유지되는 폴더를 관리하게 된다. 밥은 자신의 메시지를 자신이 생성한 폴더로 이동, 삭제하거나 중요 메시지로 표기해둘 수 있다.

profile
Back-End Web Developer

0개의 댓글