SMTP-протокол
SMTP — протокол передачи почты. У него две основные задачи. Первая — проверить настройки системы и разрешить отправку письма. Вторая — отправить сообщение и оповестить о доставке или ошибке.
Вы используете SMTP-протокол каждый раз, когда отправляете письмо по электронной почте. Не имеет значения, чем вы пользуетесь: веб-сервисами вроде Gmail, десктопными приложениями вроде Thunderbird или собственным клиентом на хостинге cloud.timeweb.com . Везде применяется сервер исходящей почты SMTP.
Немного технических подробностей
SMTP-port имеет номер 25. Через него пересылается почта между серверами. Второй SMTP-порт — 587. Через него сообщения пересылаются от почтового клиента к серверу.
Если при отправке используется защищенное соединение, то вместо TCP 25 используют порт 465. Номер порта также могут изменить, чтобы обойти ограничения провайдеров. Некоторые компании блокируют 25 порт, чтобы избежать потоков спама.
Команды и ответы
Команды SMTP состоят из четырех символов. Вместе с ними могут указываться необязательные параметры, которые определяют тип данных.
Ответы составлены из двух частей:
- Код сообщения — нужен для проверки корректности отправки.
- Текстовое сообщение — объясняет, что случилось при отправке или получении. Чаще всего оно предназначено для людей, а не компьютеров.
Что означает email с кодом ошибки? Зависит от того, какие цифры вы получили. Коды сообщений начинаются на цифры 2, 3 и 5.
Логика та же, что и в кодах статуса HTTP-запросов. Если код начинается с 2, это значит, что команда выполнена успешно. Цифра 3 в начале кода говорит о том, что SMTP-сервер нуждается в дополнительных данных. Если код начинается с цифры 5, то произошел сбой на стороне сервера.
Принцип работы SMTP
Чтобы понять, какие действия выполняет сервер электронной почты SMTP, достаточно хотя бы на базовом уровне понимать, как работает электронная почта .
Например, вы хотите написать другу электронное письмо. Для этого даже настроили свой почтовый сервер — это несложно. Как проходит процесс снаружи и внутри:
- Вы указываете адрес отправителя. Система определяет его принадлежность и соединяется с нужным сервисом — например, с Mail.
- Бэкенд получает данные: почтовые адреса отправителя и адресата (или нескольких адресатов), тему и содержание сообщения.
- Система ищет SMTP-сервер адресата (или нескольких адресатов).
Дальше процесс разделяется в зависимости от результатов поиска. Если сервер не обнаружен или не реагирует на запрос, система отправляет еще несколько запросов. В случае неудачи отправителю приходит сообщение об ошибке. Письмо не уходит, а отправитель получает подробное описание проблемы.
Если поиск сервера получателя прошел успешно, то включается проверка почты по IMAP — что это такое, знать необязательно в рамках изучения SMTP. Если коротко, то это еще один протокол электронной почты , который проверяет подлинность отправки. Существуют и другие почтовые протоколы — например, POP3.
Пример работы протокола
Особенность SMTP в том, что серверы того, кто отправляет письмо, и того, кто его получает, постоянно общаются. Пересылка не происходит одним запросом. Сначала серверы здороваются, затем обмениваются по очереди важной информацией: от кого письмо, что внутри.
Для наглядности пример очень простого обмена командами и ответами:
$ telnet expamlemail.com 25 — проверяем, можно ли подключиться к порту 25.
Trying examplemail.com.
Connected to examplemail.com.
220 mailserver at examplemail.com greets you — есть контакт.
HELO testmail.com
250 examplemail.com — поприветствовали друг друга с помощью команды HELO. Сервер получателя отправил код 250. Это значит, что можно продолжить общение.
MAIL FROM: — мы сообщаем, от кого собираемся отправить письмо.
250 2.1.0 Ok — сервер отвечает, что не против того, чтобы принять письмо от этого адресата. На этом этапе уже могут возникать ошибки. Например, если указанный адрес отправителя внесен в черный список получателя или почтового сервиса.
RCPT TO: — мы сообщаем, кому хотим отправить сообщение.
250 2.1.5 Ok — сервер говорит, что готов принять письмо для этого получателя. На этом этапе могут возникать ошибки, если, например, адрес получателя указан неверно.
DATA — говорим серверу, что передача письма сейчас начнется.
354 End data with . — сервер подсказывает, в каком виде должен быть конец письма.
FROM: test@testmail.com — начинаем передачу письма вместе с техническими заголовками.
TO: user@examplemail.com
SUBJECT: Test header
Some text
. — показываем, что передача письма завершена.
250 2.0.0 Ok: queued as 1CCD5D74AAE — сервер уведомляет, что принял письмо и назначил ему ID. Идентификатор нужен, чтобы администратор принимающего сервиса при недоставке письма мог найти причину ошибки.
QUIT — сообщаем серверу, что сеанс связи закончен.
221 2.0.0 Bye — сервер прощается.
Connection closed by foreign host — соединение обрывается.
Проблемы безопасности
SMTP — простой протокол. По умолчанию у него нет средств защиты пользовательских данных. Шифрование добавили, но оно работает только при использовании STARTTLS, а не «из коробки». То есть зашифрованное соединение создается поверх обычного.
Еще одна большая проблема этого протокола — огромное количество спама. Для защиты от него приходится использовать внешние инструменты.
Тем не менее SMTP остается популярным решением для обмена сообщениями. Большинство пользователей не замечает его недостатков, потому что защищены теми механизмами, которые внедряют почтовые сервисы.
Когда стоит создавать свой SMTP-сервер
В большинстве случаев пользователям хватает возможностей, которые предоставляют SMTP-серверы бесплатных почтовых сервисов: Gmail, Яндекс.Почты, Mail.ru. Однако их достоинства становятся несущественными, когда требуется массовая рассылка. Причина — ограничения по количеству писем.
Например, через бесплатную почту Яндекса нельзя отправлять более 150 писем в сутки, а на Mail.ru используется лимит 1 письмо в минуту. Если превысить порог, письма будут падать в папку «Спам». Получатели рискуют их не увидеть.
Решением может стать создание собственного SMTP-сервера. Это посильная задача. SMTP — простой и хорошо задокументированный протокол. Его можно быстро проверить, есть подробный отчет об ошибках.
Но у такого подхода есть и недостатки. Для доработки под свои задачи нужны разработчики. К тому же не все провайдеры поддерживают SMTP, потому что часто он становится источником спама. Поэтому чаще для массовых рассылок используют специализированные сервисы.
Создание же собственного SMTP-сервиса может быть разумным для организации внутрикорпоративной почты, доступ к которой есть только у авторизованных пользователей.
Почтовая кухня #2: SMTP
SMTP (англ. Simple Mail Transfer Protocol — простой протокол передачи электронной почты) — это сетевой протокол, предназначенный для передачи электронной почты в сетях TCP/IP.
ESMTP (англ. Extended SMTP) — масштабируемое расширение протокола SMTP. В настоящее время под «протоколом SMTP», как правило, подразумевают ESMTP и его расширения.
Сразу отмечу, что в настоящее время SMTP в чистом виде практически не используется, т.к. он даже не поддерживает элементарно авторизацию… Используется ESMTP. Когда/если вы отправляете почту почтовым клиентом (Outlook, Thunderbird, Evolution, TheBat) происходит работа именно по этому протоколу.
Для работы по этому протоколу нужно соединиться с почтовым сервером по определенному порту и отправить некоторую последовательность ESMTP команд.
Команда представляет из себя строку вида
КОМАНДА[пробел]параметр(опционально)
В ответ на команду сервер возвращает строку вида
XXX[пробел]доп. информация
При этом XXX число в ответе сервера обозначает:
2ХХ — команда успешно выполнена
3XX — ожидаются дополнительные данные от клиента
4ХХ — временная ошибка, клиент должен произвести следующую попытку через некоторое время
5ХХ — неустранимая ошибка
Так вот, давайте перейдем ближе к делу — попробуем элементарно отправить e-mail из консоли через какой-нибудь почтовый сервер (не важно, линукс у вас или виндоус). Так будет проще познакомиться с этим протоколом — сразу на практике. Привожу комманды и параллельно объясняю их значение.
Для нашего эксперимента буду использовать почтовый сервер яндекса. Подразумевается, что уже есть там аккаунт…
Сразу предупреждаю, что после соединения все команды нужно вводить максимально быстро, т.к. при задержке около 15 секунд соединение автоматически разрывается. Рекомендую сперва все команды заранее набрать в текстовом редакторе а после просто вставлять их в командную строку.
telnet smtp.yandex.ru 2025 #соединяемся с smtp почтовым сервером. Адрес и порт smtp сервера можно посмотреть в инструкциях на сайте почтовика
Ответ:
Trying 213.180.204.38…
Connected to smtp.yandex.ru.
Escape character is ‘^]’.
220 Yandex ESMTP (NO UCE)(NO UBE) server ready at Mon, 2 Feb 2009 13:47:22 +0300
Код 220 говорит об успешном соединении
EHLO [91.198.212.5] #Приветствуем сервер и отсылаем ему наш внешний IP (IP не обязательно отсылать, можно обойтись просто EHLO, но сервер скорее всего на это ругнется)
UPD: Желательно отправлять даже не IP а доменное имя для этого IP вродеEHLO you.provider.domain без квадратных скобок
Ответ:
250-smtp18.yandex.ru Hello 91.198.212.5
250-SIZE 20971520
250-8BITMIME
250-PIPELINING
250-CHUNKING
250-ENHANCEDSTATUSCODES
250-DSN
250-X-RCPTLIMIT 25
250-AUTH=LOGIN
250-AUTH LOGIN
250-STARTTLS
250 HELP
Сервер принял приветствие и выслал список поддерживаемых команд. Из этого списка нас интересует AUTH LOGIN. Это команда для авторизации на сервере по base64-закодированному логину и паролю. Так вот, нужно заранее подготовить закодированные в base64 пароль и логин от вашей почты. Можно это сделать, например, здесь seriyps.ru/crypt или командой в Linux echo [ваш пароль/логин] | base64
AUTH LOGIN # Сообщаем серверу о намерении пройти авторизацию
Ответ:
Этот самый VXNlcm5hbWU6 — закодированное в base64 слово “Username:”, а номер ответа 3ХХ означает, что сервер ждет от нас дополнительной информации. Не будем его огорчать:
ВАШ_ЛОГИН_ПОЧТЫ_В_BASE_64 #Отправляем ваш логин почты в base64, например dmFzaWFwdXBraW4=
Ответ:
Это, как можно догадаться, “Password:” в base64
ВАШ_ПАРОЛЬ_ПОЧТЫ_В_BASE_64 # Отправляем пароль почты в base64, например MTIzNDU2
Ответ:
т.е. авторизация прошла успешно. Теперь можно отправлять e-mail)
MAIL FROM: vasiapupkin@ya.ru # Сообщаем, что хотим отправить почту с адреса vasiapupkin@ya.ru Адрес может быть любым (в том числе с несуществующих доменов, однако он может проверяться при проверке на спам)
Ответ:
RCPT TO: billy@microsoft.com # Сообщаем, что хотим отправить письмо на адрес billy@microsoft.com
Ответ:
DATA # Здесь сообщаем, что начинаем передачу данных.
Ответ:
Т.е. сервер будет считывать введенные в консоли данные до того момента, пока мы не нажмем Энтер точка Энтер (после этой комбинации письмо сразу отправляется)
- Заголовков SMTP-протокола (то, что мы вводим при MAIL FROM: и RCPT TO: плюс некоторая служебная информация)
- Заголовков письма. (отправитель, обратный адрес, адресат, отметки о спам-проверках, тема письма, MIME-тип, кодировка и т.п.)
- Тела письма. (отделяется от заголовков пустой строкой, обычный ASCII текст либо соответствующий mime типу набор данных)
Два раза Энтер, затем вводим сам текст письма.
Hello, Billy! You’ll die tomorrow!
Энтер. Энтер # Сообщаем, что закончили передачу сообщения
Ответ:
Т.е. сообщение принято для передачи
Теперь можно отправить еще какое-нибудь письмо (MAIL FROM: RCPT TO:) или завершить сеанс работы
QUIT # Завершаем сеанс
Ответ:
Это все. Как видно, протокол довольно простой, основные сложности — в формировании самого тела письма.
Резюмируя:
telnet smtp.yandex.ru 2025
EHLO 91.198.212.5
AUTH LOGIN
ВАШ_ЛОГИН_ПОЧТЫ_В_BASE_64
ВАШ_ПАРОЛЬ_ПОЧТЫ_В_BASE_64
MAIL FROM: vasiapupkin@ya.ru
RCPT TO: billy@microsoft.com
DATA
From: Вася Пупкин
To: Билли Г
Subject: Hello Billy
Hello, Billy! You will be die tomorrow!
Энтер . Энтер
QUIT
Конечно, здесь не приведена информация по отправке почты в кодировках текста, отличных от ASCII, не написано про вложенные файлы и MIME но если вам нужны подробности, вот несколько ссылок:
Электронная_почта Wiki
SMTP Wiki
MIME Wiki
rfc5321
При разработке приложений непосредственно с SMTP обычно работать не приходится, для этого используют различные фреймворки или стандартные функции. Для PHP можно посмотреть:
SMTP PEAR расширение
PHPMailer библиотека для работы с электронной почной
Удачных экспериментов!