Logo
Englika

Как работает электронная почта

Как работает электронная почта

Давайте представим, что Джон решил написать письмо Кейт и рассказать ей о своей поездке в горы. Джон подходит к компьютеру и открывает свой любимый почтовый клиент (Mail User Agent, MUA). Почтовым клиентом может быть как программа, установленная на компьютере (напр, Apple Mail, Microsoft Outlook и др), так и веб-клиент (напр, Gmail и др). Джон составляет письмо, красочно описывая все подробности своего путешествия, в поле «Кому» указывает электронную почту Кейт (напр, kate@gmail.com) и нажимает кнопку «Отправить». Затем начинается самое интересное.

Схема работы электронной почты

Схема сгенерирована тут.

Для простоты, давайте разобьем весь этот процесс на 2 этапа: отправка и получение письма. Все агенты, отвечающие за отправку, имеют цифру 1, а за получение – цифру 2. По мере прочтения статьи, рекомендую для наглядности смотреть на эту схему.

Отправка письма

Путешествие письма до Mail Transfer Agent Джона

В почтовом клиенте Джона (MUA) хранятся адреса серверов входящей (где получать новые входящие письма) и исходящей почты (кому Джон должен отправлять новые исходящие письма). Если в качестве почтового клиента используется отдельная программа (напр, Apple Mail, Microsoft Outlook и др), то при добавлении почтового ящика, помимо адреса электронной почты и пароля, у вас попросят ввести адреса входящей и исходящей почты. Хотя, если ваш почтовый ящик размещен на каком-нибудь популярном почтовом сервере (напр, gmail.com), то, скорее всего, почтовый клиент уже знает об этих адресах и не будет просить вас их ввести.

Почтовый клиент Джона (MUA) идет по указанному адресу исходящей почты (через SMTP на 587 порту) и его встречает Mail Submission Agent (MSA), который занимается получением писем от пользователей. Mail Submission Agent как работник на почте, единственная задача которого получать письма, которые необходимо куда-то доставить. Он никогда не будет доставлять их сам. Так же и Mail Submission Agent не занимается отправкой писем, он лишь получает их от пользователей и передает их дальше Mail Transfer Agent (MTA).

Итак, Mail Submission Agent получил письмо Джона и передал его Mail Transfer Agent.

Отправка письма в Mail Transfer Agent Кейт

Mail Transfer Agent получает письма от Mail Submission Agent, сохраняет их в очередь (mail SPOOL, Simultaneous Peripheral Operations Online), а затем поочередно отправляет их.

Сейчас на очереди письмо Джона. Mail Transfer Agent берет его и смотрит на домен адресата (kate@gmail.com -> gmail.com). Теперь MTA должен определить, где находится адрес почтового сервера, куда нужно отправить данное письмо. Не обязательно, что адрес почтового сервера находится там же, где и сайт почтового сервера. Более того, чаще всего, это разные сервера.

Чтобы узнать, где находится почтовый сервер получателя, Mail Transfer Agent делает запрос к DNS серверу и получает MX-запись (Mail Exchanger) для домена gmail.com.

# Где почтовый сервер у gmail.com?
nslookup -type=mx gmail.com
# mail exchanger = 5 gmail-smtp-in.l.google.com.
# mail exchanger = 10 alt1.gmail-smtp-in.l.google.com.
# mail exchanger = 20 alt2.gmail-smtp-in.l.google.com.
# mail exchanger = 30 alt3.gmail-smtp-in.l.google.com.
# mail exchanger = 40 alt4.gmail-smtp-in.l.google.com.

DNS сервер ответил, что gmail.com имеет 5 таких адресов с разными приоритетами (чем меньше число, тем выше приоритет). Сначала Mail Transfer Agent следует попробовать первый. Если он не доступен, то второй и т.д.

Давайте еще посмотрим, на разных ли серверах находятся почтовый сервер и сайт.

nslookup gmail-smtp-in.l.google.com
# Address: 64.233.165.27

nslookup gmail.com
# Address: 142.250.74.69

Как и ожидалось, они расположены на разных серверах.

Наконец, Mail Transfer Agent идет по первому адресу gmail-smtp-in.l.google.com почтового сервера (через SMTP на 25 порту) и передает ему письмо Джона для Кейт.

telnet gmail-smtp-in.l.google.com 25
# Trying 64.233.165.26...
# Connected to gmail-smtp-in.l.google.com.
# Escape character is '^]'.
# 220 mx.google.com ESMTP m21-20020a194355000000b0050be7106660si2252687lfj.555 - gsmtp

## Привет! Я почтовый сервер Джона.
ehlo domain.com
# 250-mx.google.com at your service, [123.123.123.123]
# 250-SIZE 157286400
# 250-8BITMIME
# 250-STARTTLS
# 250-ENHANCEDSTATUSCODES
# 250-PIPELINING
# 250-CHUNKING
# 250 SMTPUTF8

## Я хочу отправить письмо от Джона.
mail from: <john@domain.com>
# 250 2.1.0 OK m21-20020a194355000000b0050be7106660si2252687lfj.555 - gsmtp

## К Кейт.
rcpt to: <kate@gmail.com>
# 250 2.1.5 OK m21-20020a194355000000b0050be7106660si2252687lfj.555 - gsmtp

## Я готов написать сообщение (RFC 2822).
data
# 354  Go ahead m21-20020a194355000000b0050be7106660si2252687lfj.555 - gsmtp
From: "john@domain.com" <john@domain.com>
Subject: Hello Kate!
Message-Id: <ABCDEFGH-1234-5678-ABCD-ABCDEFGHIJKLM@domain.com>
To: <kate@gmail.com>
Content-Type: text/plain; charset=utf-8

Hello, Kate! 
I have only just got back from the mountains. It was so great!

## Я закончил писать сообщение.
.
# 250 2.0.0 Ok: queued as ABC123DEF45

## Пришла пора прощаться
quit
# 221 2.0.0 Bye
# Connection closed by foreign host

Ура! Mail Transfer Agent Джона успешно передал письмо Mail Transfer Agent Кейт через протокол SMTP по 25 порту.

Как можете заметить, ответ MTA всегда содержит код из 3 цифр и короткое сообщение, понятное для людей. Коды ошибок могут быть следующими:

  • 2xx – Команда выполнена успешно. Можно продолжать.
  • 3xx – Команда была принята, но сервер требует дополнительной информации. Нужно отправить другую команду с этой информацией.
  • 4xx – Команду не удалось выполнить, но это временно. Нужно повторить команду позже.
  • 5xx – Команду не удалось выполнить. Не нужно пытаться повторить ее.

Посмотрите еще раз на содержание письма, которое было отправлено после команды data. Оно состоит из 2 частей, которые разделены пустой строкой: заголовки и текст письма. Видите заголовок с названием To? Как думаете, что будет, если его поменять на другой адрес, например, на alice@domain.com? Куда будет отправлено письмо, Кейт или Алисе? Оно будет отправлено Кейт, т.к. MTA берет адрес получателя только из команды rcpt to. Все заголовки являются просто частью содержания письма, которое передается по адресу rcpt to.

Кстати, возможно, мы отправили письмо не конечному почтовому серверу Кейт, а лишь ретранслятору, который может перенаправить другому ретранслятору, но в конечном итоге это письмо достигнет нужного сервера. Ретрансляторы это те же Mail Transfer Agents, которые вместо того, чтобы сохранить письмо у себя, передают его дальше. Ретрасляторы могут помочь распределить нагрузку между несколькими серверами, предотвращая перегрузку любого отдельного сервера.

В настоящее время письмо находится у Mail Transfer Agent почтового сервера Кейт.

Получение письма

Mail Transfer Agent Кейт (MTA) принимает письмо Джона, проверяет его (является ли оно спамом, действительно ли оно пришло от указанного домена и т.д.) и если все в порядке, то передает его в Mail Delivery Agent (MDA).

Проверку на спам, обычно, осуществляет не сам MTA, а другая система (напр, Rspamd), которая использует различные методики определения является ли письмо спамом. При обнаружении спама, MTA может либо отказаться доставлять его Кейт и вернуть MTA Джона ошибку, либо добавить в письмо заголовок, указывающий, что письмо является спамом (напр, X-Spam: Yes).

В результате Mail Transfer Agent имеет 2 роли:

  1. Получать исходящие письма от Mail Submission Agent и отправлять их другим Mail Transfer Agents.
  2. Получать входящие письма от разных Mail Transfer Agents и передавать их Mail Delivery Agent.

Mail Delivery Agent сохраняет входящие письма в почтовых ящиках пользователей. Например, все входящие письма для Кейт могут хранится в /home/kate в виде файлов. Подробнее про форматы хранения писем, поддерживаемые Dovecot, можно почитать здесь (стоит обратить внимание в первую очередь на maildir и mdbox).

Mail Delivery Agent может иметь различные правила распределения входящих писем по папкам. Например, если входящее письмо имеет заголовок X-Spam: Yes, который был добавлен на предыдущем шаге, то положить это письмо в папку спам. Если ящик оказался переполненным или возникла другая ошибка, то генерируется письмо отправителю (Джону) с указанием причины, почему не удалось доставить это письмо.

На данный момент письмо уже находится в почтовом ящике Кейт, но она о нем пока не знает. Почтовый клиент Кейт (Mail User Agent) должен как-то узнать о новом письме. Для этого Mail User Agent периодически спрашивает у Mail Retrieval Agent, не появились ли новые письма (частота настраивается в почтовом клиенте). Коммуникация между ними происходит через IMAP или POP3.

Настал долгожданный момент. Почтовый клиент Кейт получил письмо от Джона и издал звуковое оповещение. Кейт подошла к компьютеру и увидела новое письмо от Джона.

Отправка ответа на письмо

Если Кейт решит ответить на письмо Джона, то кому Mail User Agent отправит его? Mail Retrieval Agent отвечает только за получение писем, он не занимается их отправкой.

Процесс отправки ответного письма будет происходить также, только в обратном порядке:

  1. Кейт составляет ответное письмо в Mail User Agent и нажимает «Отправить».
  2. Mail User Agent Кейт отправляет письмо Mail Submission Agent, который находится на почтовом сервере Кейт.
  3. Mail Submission Agent передает письмо Mail Transfer Agent.
  4. Mail Transfer Agent Кейт делает запрос к DNS серверу и получает адрес почтового сервера Джона.
  5. Mail Transfer Agent Кейт отправляет письмо Mail Transfer Agent Джона (возможно через ретрансляторы).
  6. Mail Transfer Agent Джона передает письмо в Mail Delivery Agent.
  7. Mail Delivery Agent сохраняет письмо в почтовом ящике Джона на диске.
  8. Mail User Agent Джона спрашивает у Mail Retrieval Agent не появились ли новые письма и получает письмо от Кейт.
  9. Джон читает письмо от Кейт.

Чтобы не усложнять схему выше, процесс ответа на письмо на ней не отображен, поэтому пропущены MSA со стороны Кейт и MDA, Mailbox, MRA со стороны Джона.

IMAP или POP3

IMAP (Internet Message Access Protocol) и POP3 (Post Office Protocol 3) используются почтовыми клиентами для получения писем из почтового ящика, который находится на почтовом сервере.

POP3 загружает все письма из почтового ящика на локальное устройство, после чего удаляет их из сервера. Почтовый сервер может быть настроен так, чтобы копии всех писем где-то сохранялись, однако другое устройство уже не сможет загрузить их. В итоге все письма будут доступны только с одного устройства. Если почтовый сервер не хранит копии писем, то если устройство сломается, потеряются все письма, которые на нем были.

IMAP позволяет работать с одним почтовым ящиком одновременно с нескольких устройств (напр, на компьютере, телефоне и планшете). При чтении писем, они остаются на сервере и «помечаются» как открытые (перемещаются в другую папку). IMAP поддерживает работу с разными папками в почтовом ящике (входящие, спам, черновики, отправленные, корзина, архив и др), в которых можно хранить письма. Эти папки будут видны на всех устройствах.

Ссылки на RFC для дальнейшего изучения

RFC (Request for Comments documents) определяют стандарты для Интернета. Есть несколько RFC, описывающие работу электронной почты.

  1. Simple Mail Transfer Protocol (SMTP) [RFC 2821]
  2. SMTP Service Extensions [RFC 1869]
  3. Internet Message Format [RFC 2822]
  4. Internet Message Access Protocol (IMAP) [RFC 2060]
  5. Post Office Protocol (POP) [RFC 1939]

В следующей статье мы перейдем к созданию своего почтового сервера с неограниченным количеством доменов и почтовых ящиков.

Похожие статьи

Как получить N строк для каждой группы в SQL

Давайте предположим, что вы разрабатываете главную страницу в интернет-магазине. На этой странице должны отображаться категории товаров с 10 товарами в каждой. Как сделать запрос к базе данных? Какие индексы нужно создать, чтобы ускорить выполнение...

Как получить N строк для каждой группы в SQL