Почтовый сервер на Linux / Хабр
Как наладить работу почтового сервера, умеющего принимать и отправлять электронную корреспонденцию, бороться со спамом, взаимодействовать с клиентами? На самом деле, всё довольно просто.
Сегодня поговорим о почтовых серверах на Linux. Мы расскажем о том, как настроить сервер, о широко распространённом в интернете протоколе SMTP, а также о других протоколах, таких, как POP и IMAP. В итоге вы окажетесь обладателем полноценной системы для работы с электронной почтой.
Начнём с SMTP-сервера на Linux
SMTP-сервер
Протокол SMTP (Simple Mail Transfer Protocol) определяет правила пересылки почты между компьютерами, при этом, он не регламентирует правила хранения или визуализации сообщений. Это системно-независимый протокол, то есть, отправитель и получатель почты могут иметь различные ОС.
SMTP требует лишь чтобы сервер был способен отправлять обычный ASCII-текст другому серверу, используя порт 25, который является стандартным портом SMTP.
Сегодня в большинство дистрибутивов Linux встроены две наиболее распространённых реализации SMTP: sendmail и postfix.
Sendmail — это популярный почтовый сервер с открытым кодом, используемый во многих дистрибутивах Linux. К его минусам можно отнести несколько усложнённую архитектуру и недостаточно высокий уровень защиты.
Postfix — система немного более продвинутая, при разработке этого почтового сервера особое внимание было уделено вопросам безопасности.
Компоненты почтовой службы
Типичная почтовая служба состоит из трёх основных компонентов:
Почтовый клиент, который ещё называют почтовым агентом (Mail User Agent, MUA). Именно с ним взаимодействует пользователь, например — это почтовые клиенты Thunderbird или Microsoft Outlook. Они позволяют пользователю читать почту и писать электронные письма.
Почтовый сервер, или агент пересылки сообщений (Mail Transport Agent, MTA). Этот компонент ответственен за перемещение электронной почты между системами, этим занимаются, например, Sendmail и Postfix.
Агент доставки электронной почты (Mail Delivery Agent, MDA). Этот компонент ответственен за распределение полученных сообщений по почтовым ящикам пользователей. Например, это Postfix-maildrop и Procmail.
Установка почтового сервера
Для настройки нашего сервера был выбран пакет Postfix. Это — популярный среди системных администраторов выбор, стандартный почтовый сервер в большинстве современных дистрибутивов Linux.
Начнём, проверив, установлен ли Postfix в системе:
$ rpm -qa | grep postfix
Если обнаружить Postfix не удалось, установить его, например, в дистрибутивах, основанных на Red Hat, можно с помощью такой команды:
$ dnf -y install postfix
Затем запустим службу postfix и организуем её автозапуск при загрузке системы:
$ systemctl start postfix $ systemctl enable postfix
В дистрибутивах, основанных на Debian, вроде Ubuntu, установить Postfix можно так:
$ apt-get -y install postfix
В ходе установки будет предложено выбрать конфигурацию сервера.
Настройка сервера
После установки почтового сервера Postfix, его нужно настроить. Большинство конфигурационных файлов находятся в директории /etc/postfix/.
Главный конфигурационный файл Postfix можно найти по адресу /etc/postfix/main.cf. Здесь имеется множество параметров, рассмотрим самые важные.
myhostname
Этот параметр используется для указания имени хоста почтовой системы. Это — имя хоста в интернете, для которого Postfix будет получать почту.
Типичные примеры имён хостов почтовых серверов — mail.example.com и smtp.example.com.
Настраивают этот параметр так:
myhostname = mail.example.com
mydomain
Эта настройка позволяет указать почтовый домен, обслуживанием которого занимается сервер, например — example. com:
mydomain = example.com
myorigin
Этот параметр позволяет указать доменное имя, используемое в почте, отправленной с сервера. Присвоим ему значение $mydomain:
myorigin = $mydomain
В настройках можно ссылаться на параметры, добавляя знак $
перед именем переменной.
mydestination
Этот параметр содержит список доменов, которые сервер Postfix будет считать конечными пунктами назначения для входящей почты.
В нашем случае здесь будут имя хоста сервера и доменное имя, но данный параметр может содержать и другие имена:
mydestination = $myhostname, localhost.$mydomain, $mydomain, mail.$mydomain, www.$mydomain
mail_spool_directory
Почтовый сервер Postfix может использовать два режима доставки почты:
- Непосредственно в почтовый ящик пользователя.
- В центральную директорию очередей, при этом почта попадает в папку /var/spool/mail, где имеется файл для каждого пользователя.
mail_spool_directory = /var/spool/mail
mynetworks
Эта переменная — важный параметр настройки. Она позволяет указывать то, какие сервера могут пересылать почту через сервер Postfix.
Обычно разрешают передачу почты только от локальных клиентских компьютеров. В противном случае вашим сервером могут заинтересоваться спамеры.
Если неправильно настроить параметр mynetworks, спамеры вполне смогут воспользоваться сервером как ретранслятором почты. Это очень быстро приведёт к тому, что какая-нибудь система борьбы со спамом поместит его в один из чёрных списков, вроде DNS Blacklist (DNSBL), или Realtime Blackhole List (RBL). Как только сервер попадёт в подобный список, очень немногие смогут получить письма, отправленные с его помощью.
Вот как может выглядеть настройка этого параметра:
mynetworks = 127.0.0.0/8, 192.168.1.0/24
smtpd_banner
Эта переменная позволяет задать ответ, который возвращает сервер при подключении клиентов.
Лучше всего поменять это значение так, чтобы оно не указывало на то, какой именно используется почтовый сервер.
inet_protocols
Эта переменная позволяет задавать версию IP, которую будет использовать Postfix при установлении соединений.
inet_protocols = ipv4
Для того, чтобы изменения, внесённые в конфигурационные файлы, вступили в силу, службу Postfix надо перезагрузить:
$ systemctl reload postfix
На самом деле, в конфигурационном файле Postfix можно ещё много чего настроить. Например — управлять уровнями безопасности, задавать опции отладки и другие параметры.
Возможно, настраивая сервер, вводя значения параметров, вы допустите ошибку. Проверить правильность настроек можно с помощью такой команды:
$ postfix check
С помощью этого средства можно найти строку, в которой допущена ошибка, и исправить её.
Проверка очереди сообщений
Иногда очередь почтовых сообщений переполняется. Это может быть вызвано множеством факторов, вроде сетевой ошибки, или по любой причине, способной задержать отправку почты.
Для того чтобы проверить очередь сообщений, воспользуйтесь такой командой:
$ mailq
Она выведет сообщения, находящиеся в очереди. Если очередь переполнена и на отправку сообщения уходит по несколько часов, можно инициировать процесс отправки сообщений такой командой:
$ postfix flush
Если теперь проверить очередь, она должна оказаться пустой.
Тестирование почтового сервера
После настройки сервера на Postfix, его надо протестировать. Первый шаг в тестировании — использование локального почтового клиента, вроде mailx или mail (это — символьная ссылка на mailx).
Попробуйте отправить письмо кому-нибудь, чей адрес обслуживается на том же сервере, а если это сработает — отправьте письмо на адрес, который находится где-нибудь ещё.
$ echo "This is message body" | mailx -s "This is Subject" -r "likegeeks<[email protected]>" -a /path/to/attachment [email protected]
Затем попробуйте принять письмо, отправленное с другого сервера.
Если вы столкнётесь с проблемами — проверьте логи. В дистрибутивах, основанных на Red Hat, то, что вам надо, можно найти по адресу /var/log/maillog. В Debian-дистрибутивах нужный файл можно найти здесь: /var/log/mail.log, или же по пути, заданному в настройках rsyslogd. Вот, если нужно, материал о логировании в Linux, и о том, как настраивать rsyslogd.
Если проблемы всё ещё не решены, попытайтесь проверить настройки DNS, взгляните на MX-записи, используя сетевые команды Linux.
Борьба со спамом
Существует немало решений для выявления среди почтовых сообщений нежелательных писем — спама. Одно из лучших — проект с открытым исходным кодом SpamAssassin.
$ dnf -y install spamassassin
Затем надо запустить соответствующую службу и добавить её в автозагрузку:
$ systemctl start spamassassin $ systemctl enable spamassassin
После установки SpamAssassin, взгляните на его настройки в файле /etc/mail/spamassassin/local. cf.
SpamAssassin умеет отличать обычные письма от спама, основываясь на результатах исследования корреспонденции с помощью различных скриптов. Результаты проверок оцениваются в баллах.
Чем выше итоговая оценка письма — тем выше и вероятность того, что оно является спамом.
В конфигурационном файле параметр required_hits 5 указывает на то, что SpamAssassin пометит сообщение как спам, если его рейтинг составляет 5 или выше.
Параметр report_safe принимает значения 0, 1, или 2. Установка его в 0 означает, что письма, помеченные как спам, пересылаются в исходном виде, но их заголовок модифицируется с указанием на то, что они являются спамом.
Если этот параметр установлен в значение 1 или 2, SpamAssassin сгенерирует отчёт и отправит его получателю.
Разница между значениями 1 и 2 заключается в том, что в первом случае спам-сообщение будет закодировано в формате message/rfc822, а во втором — в формате text/plain.
Кодирование text/plain безопаснее, так как некоторые почтовые клиенты исполняют сообщения формата message/rfc822, что при определённых условиях может привести к заражению клиентского компьютера вирусом.
После установки и настройки SpamAssassin, нужно интегрировать его с Postfix. Пожалуй, легче всего это сделать с помощью использования procmail.
Создадим файл /etc/procmailrc и добавим в него следующее:
:0 hbfw | /usr/bin/spamc
Затем отредактируем файл настроек Postfix — /etc/postfix/main.cf, задав параметр mailbox_command следующим образом:
mailbox_command = /usr/bin/procmail
И, наконец, перезапустим службы Postfix и SpamAssassin:
$ systemctl restart postfix $ systemctl restart spamassassin
Надо сказать, что SpamAssassin не всегда распознаёт спам, что ведёт к наполнению почтовых ящиков ненужными письмами.
К счастью, сообщения, прежде чем они достигнут почтового сервера на Postfix, можно фильтровать, используя Realtime Blackhole Lists (RBLs). Это снизит нагрузку на почтовый сервер и поможет сохранить его в чистоте.
Откройте конфигурационный файл Postfix /etc/postfix/main.cf, измените параметр smtpd_recipient_restrictions и настройте другие параметры следующим образом:
strict_rfc821_envelopes = yes relay_domains_reject_code = 554 unknown_address_reject_code = 554 unknown_client_reject_code = 554 unknown_hostname_reject_code = 554 unknown_local_recipient_reject_code = 554 unknown_relay_recipient_reject_code = 554 unverified_recipient_reject_code = 554 smtpd_recipient_restrictions = reject_invalid_hostname, reject_unknown_recipient_domain, reject_unauth_pipelining, permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, reject_rbl_client dsn.rfc-ignorant.org, reject_rbl_client dul.dnsbl.sorbs.net, reject_rbl_client list.dsbl.org, reject_rbl_client sbl-xbl.spamhaus.org, reject_rbl_client bl.spamcop.net, reject_rbl_client dnsbl.sorbs.net, permit
Затем перезагрузите сервер Postfix:
$ systemctl restart postfix
Вышеприведённые чёрные списки используются чаще всего, но вы можете найти и другие подобные сервера.
Защита SMTP-соединения
Лучше всего передавать SMTP-трафик по TLS для защиты его от атаки через посредника.
Для начала нужно сгенерировать сертификат и ключ с использованием команды openssl:
$ openssl genrsa -des3 -out mail.key $ openssl req -new -key mail.key -out mail.csr $ cp mail.key mail.key.original $ openssl rsa -in mail.key.original -out mail_secure.key $ openssl x509 -req -days 365 -in mail.csr -signkey mail_secure.key -out mail_secure.crt $ cp mail_secure.crt /etc/postfix/ $ cp mail_secure.key /etc/postfix/
Затем надо добавить в файл настроек Postfix /etc/postfix/main.cf следующее:
smtpd_use_tls = yes smtpd_tls_cert_file = /etc/postfix/mail_secure.crt smtpd_tls_key_file = /etc/postfix/mail_secure.key smtp_tls_security_level = may
И, наконец, нужно перезагрузить службу Postfix:
$ systemctl restart postfix
Теперь, при подключении клиента к серверу, нужно выбрать TLS. Тут вы, при первой отправке почты после изменении настроек, увидите предупреждение, так как сертификат не подписан.
Основы протоколов POP3 и IMAP
Итак, мы наладили процесс отправки и получения электронных писем по SMTP, но на этом организация полноценной почтовой службы не заканчивается. Рассмотрим следующие ситуации:
- Пользователям нужны локальные копии электронных писем для их просмотра без подключения к интернету.
- Почтовые клиенты пользователей не поддерживают формат файлов mbox. Это — простой текстовый формат, который могут читать многие консольные почтовые клиенты, вроде mailx и mutt.
- Пользователи не могут постоянно пользоваться быстрым подключением для доступа к файловой системе сервера и для работы с mbox-файлами, в итоге нужно сделать локальную копию для работы с ними без подключения к сети.
- Ограничения безопасности указывают на то, чтобы у пользователей не было прямого доступа к шлюзу электронной почты, например, не допускается работа с общедоступными папками очередей сообщений.
Для того, чтобы учесть все эти особые случаи, были созданы другие протоколы. Их можно описать как протоколы для доступа к электронной почте.
Сильнее всего распространены два популярных протокола доступа к почте — POP (Post Office Protocol), и IMAP (Internet Message Access Protocol).
В основе POP лежит очень простая идея. Центральный почтовый сервер на Linux всё время подключён к интернету, он получает и сохраняет письма для всех пользователей. Все полученные письма остаются в очереди на сервере до тех пор, пока пользователь не подключится к нему по протоколу POP и не загрузит письма.
Когда пользователь хочет отправить письмо, почтовый клиент обычно передаёт его через центральный сервер по SMTP.
Обратите внимание на то, что SMTP-сервер и POP-сервер могут без проблем работать на одной и той же машине. В наши дни это — обычная практика.
Возможности, вроде хранения исходных экземпляров писем пользователей на сервере с хранением на клиенте лишь кэшированных копий, в POP отсутствуют. Это привело к разработке протокола IMAP.
Используя IMAP, сервер будет поддерживать три режима доступа к почте:
- Онлайн-режим похож на прямой доступ к файловой системе на почтовом сервере.
- Оффлайн-режим похож на то, как работает POP, когда клиент отключается от сети после получения своих писем. В этом режиме сервер обычно не хранит копии писем.
- Автономный режим позволяет пользователям хранить кэшированные копии своих писем, а сервер так же хранит копии этих писем.
Существуют различные реализации IMAP и POP, в этой сфере весьма популярен сервер Dovecot, который позволяет работать с обоими протоколами.
Сервера POP3, POP3S, IMAP, и IMAPS слушают, соответственно, порты 110, 995, 143, и 993.
Установка Dovecot
Большинство дистрибутивов Linux содержат предустановленный Dovecot, однако, его можно установить и самостоятельно. В системах, основанных на Red Hat, это делается так:
$ dnf -y install dovecot
В системах, основанных на Debian, функционал IMAP и POP3 предоставляются в двух разных пакетах:
$ apt-get -y install dovecot-imapd dovecot-pop3d
Тут вам предложат создать самозаверенный сертификат для работы с IMAP и POP3 по SSL/TLS. Ответьте на вопрос yes и, при появлении соответствующего запроса, введите имя хоста вашей системы.
Затем можно запустить соответствующую службу и добавить её в автозагрузку:
$ systemctl start dovecot $ systemctl enable dovecot
Настройка Dovecot
Главный файл настроек Dovecot расположен по адресу /etc/dovecot/dovecot.conf. В некоторых дистрибутивах Linux этот файл размещается в папке /etc/dovecot/conf.d/ и, для подключения файлов настроек, используется директива include.
Вот некоторые из параметров, используемых для настройки Dovecot.
protocols: протоколы, которые надо поддерживать.
protocols = imap pop3 lmtp
Здесь lmtp означает Local Mail Transfer Protocol. listen: IP-адрес, который будет слушать сервер.
listen = *, ::
Здесь звёздочка означает все интерфейсы IPv4, двойное двоеточие означает все интерфейсы IPv6.
userdb: база данных пользователей для аутентификации.
userdb { driver = pam }
mail_location: это запись в файле /etc/dovecot/conf.d/10-mail.conf. Выглядит она так:
mail_location = mbox:~/mail:INBOX=/var/mail/%u
Dovecot поставляется со стандартными SSL-сертификатами и файлами ключей, которые используются в файле /etc/dovecot/conf.d/10-ssl.conf.
ssl_cert = </etc/pki/dovecot/certs/dovecot.pem ssl_key = </etc/pki/dovecot/private/dovecot.pem
Когда пользователь пытается подключиться к Dovecot, сервер покажет предупреждение, так как сертификаты не подписаны. Если нужно, подписанные сертификаты можно приобрести в подходящем центре сертификации.
Не забудьте открыть порты сервера Dovecot на файрволе.
$ iptables -A INPUT -p tcp --dport 110 -j ACCEPT $ iptables -A INPUT -p tcp --dport 995 -j ACCEPT $ iptables -A INPUT -p tcp --dport 143 -j ACCEPT $ iptables -A INPUT -p tcp --dport 993 -j ACCEPT
И про SMTP-порт не забудьте.
$ iptables -A INPUT -p tcp --dport 25 -j ACCEPT
Затем сохраните правила. Если хотите освежить в памяти особенности работы с iptables в Linux, взгляните на этот материал.
Или, если вы используете firewalld, можете поступить так:
$ firewall-cmd --permanent --add-port=110/tcp --add-port=995 $ firewall-cmd --permanent --add-port=143/tcp --add-port=993 $ firewall-cmd --reload
А, если что-то пошло не так, посмотрите лог-файлы /var/log/messages, /var/log/maillog, и /var/log/mail.log.
Итоги
Теперь вы можете настроить почтовую службу на своём Linux-сервере. Как видите, много времени это не займёт. Конечно, у рассмотренных здесь пакетов, вроде Postfix, уйма настроек, но если вы освоили описанную здесь последовательность действий и разобрались с основами, то всё, что вам понадобится, несложно будет выяснить из документации.
Уважаемые читатели! А как вы настраиваете почтовые сервера на Linux?
Никогда не проверяйте e-mail адреса по стандартам RFC / Хабр
Множество сайтов требуют от пользователя ввода адреса электронной почты, и мы, как крутые и щепетильные разработчики, всегда стремимся проверять формат введенных адресов строго по стандартам RFC. Благодаря этому наши приложения и сайты проверяют формат e-mail корректно и не имеют проблем с юзабилити, а мы сладко спим, потому что уверены, что все работает как надо.
Ага, как бы не так!
Приведенные выше аргументы звучат круто и железобетонно, но проблема здесь заключается в том, что в адресе почты могут находиться совершенно бессмысленные вещи, и, на деле, проверка адресов по стандартам RFC может, наоборот, все жутко запутать.
Почему так? Существует множество способов сформировать адрес почты, который будет одновременно и корректным и бредовым. Отчасти это происходит из-за того, что некоторые почтовые службы в целях обратной совместимости позволяют представлять адреса в форматах, которые давно устарели. Например это электронная почта существовавшая до появления DNS и до появления современного формата [email protected]: тогда использовались UUCP ”bang path” — адреса, которые представляли собой список всех узлов по маршруту ответственных за доставку.
Внутренности адреса почты
Адрес e-mail выглядит так:
mailbox@hostname
Тут mailbox может быть локальным аккаунтом пользователя, аккаунтом роли или маршрутизатором автоматизированной системы такой, например, как список рассылки, а в качестве hostname может быть использован любой узел, если о нем известно DNS-серверу, к которому обращается почтовик при доставке.
Кроме того, некоторые системы позволяют добавлять теги к адресу. Обычно это происходит в формате:
mailbox+tag@hostname
где тег и разделитель (обычно это «+», но qmail использует «-» по-умолчанию, хотя может быть сконфигурирован и иначе) игнорируются при доставке. Обычно это используется для фильтрации почты по папкам и автоматизации, но может быть использовано и для разделения введенных адресов по получателям и выявления злоупотреблений персональными данными.
Итак, в адресе в формате «mailbox@hostname», «mailbox» является пользовательским аккаунтом, приложением или аккаунтом системной роли, но может содержать и такие экстравагантные вещи, как информацию для дальнейшей маршрутизации или идентификаторы используемые для сортировки, автоматизации или отслеживания, а «hostname» — обычно доменное имя, но может являться и субдоменом, сервером, сервисом, ip-адресом или просто именем хоста.
Корректные имена ящика с точки зрения RFC
Специцификация одобряет довольно странные адреса, и было бы накладно поддерживать их все потому, что некоторые слишком сложны, и не слишком много людей обладают достаточными знаниями чтобы выделывать такие пируэты в нейминге. Поддержка таких адресов затруднит поддержку таких аккаунтов вашими сотрудниками, к тому же они почти никогда не используются в быту. _`{}|[email protected] <== Корректный адрес вряд ли достойный поддержки
Кстати, проверяйте апострофы, апострофы должны поддерживаться:
Miles.O'[email protected] <== Стоит поддерживать
Апострофы не должны закавычиваться или эскейпиться, но когда вы сохраняете такие адреса в базу или передаете еще куда-то, убедитесь, что всё чики-пуки.
В Википедии есть еще куча примеров.
Нужна ли полная совместимость с RFC? Вам выбирать, но я не советую — пробелы и нестандартные символы в адресе довольно необычная штука и чаще всего являются просто опечаткой. Крупные e-mail провайдеры не разрешают использовать это примерно по тем же причинам; таким образом обычно достаточно дозволять буквы, цифры, точки, подчеркивания, дефисы, апострофы и плюсы.
Регистрозависимые адреса
Согласно RFC уникальность адреса определяется его регистрозависимой уникальностью, однако 99,9% провайдеров считают иначе и не позволяют регистрировать VasyaPetrov@example. com, если [email protected] уже зарегистрирован. Считайте, что имя почтового ящика регистронезависимо:
[email protected] [email protected] [email protected]
Небольшая кучка систем использует полную проверку регистра, позволяя лишь адрес [email protected] и отбрасывая входящую корреспондецию всех остальных АлЛеНоВ, однако это не работает на практике, поскольку пользователь не привык различать регистр в адресах почты.
Должны ли вы тут сохранять совместимость с RFC? Конвертируя адреса в нижний регистр перед сохранением вы можете доставить проблем небольшому количеству пользователей (вы не сможете посылать им письма), но отослав миллионы e-mail я столкнулся с этим всего несколько раз.
Конвертация в адреса в нижний регистр является неплохой идеей в плане нормализации данных, так как домен всегда регистронезависим и должен быть в нижнем регистре. Если же вы решите сохранять адрес так, как он введен, добавьте поле, в котором будет хранить каноническую версию.
Нестандартные символы
Gmail тут отличился: в то время как стандарт включает в себя точку как стандартный символ, Gmail не делает различий между адресами ящиков с точками и без. Эти адреса указывают на один и тот же почтовый ящик:
[email protected] [email protected] [email protected]
Обратите внимание, что Google Apps позволяет использовать Gmail на любом домене.
Основная проблема здесь заключается в поиске адреса в базе в том виде, в котором он был изначально введен, что может доставить немало геморроя как пользователю, так и службе поддержки, а также и программистам с тестировщиками. Тут то вам и пригодится вторая, канонiческая форма адреса, но об этом позже.
Расширенная форма названия ящиков с использованием тегов.
Как было сказано выше, большинство систем доставки электронной почты (MTA), включая sendmail, Postfix, qmail, Yahoo Plus и Gmail поддерживают расширенное название ящика. Это позволяет пользователю, добавляя тег, сортировать письма. Это может позволить мне насоздавать кучу аккаунтов на одном сайте или в приложении:
[email protected] [email protected]
Но нужно ли вычищать теги из адреса ящика?
НЕТ! Будьте дружелюбны к своим пользователям, и пользователи проникнутся верой, что вы не осуществите хищение и сбыт их персональных данных с целью наживы. Даже если вы пытаетесь запретить регистрацию дополнительных аккаунтов с существующим ящиком, представьте себе, насколько просто в наше время тупо зарегистрировать еще один ящик чтобы снова зарегистрироваться у вас — не сложнее создания алиаса или папки(но об алиасах, папках и тегах, наоборот, мало кто знает).
Итак, еще раз. Создание второй, канонической, формы сохранения адреса в базе может неплохо прикрыть
вас в случае неприятностей. Убедитесь, что вы ликвидировали из нее все теги, точки и т. д. и можете сравнивать с ней свежевведенные адреса.
Юникод и интернационализированные имена ящиков
Имена ящиков не поддерживают расширенные символы ASCII (8-bit) и символы Юникода. Это ограничение уходит своими корнями в спецификацию SMTP, во времена появления которого всего этого попросту не существовало; однако 8-битные значения, определенные локально, например из кодировок семейства ISO-8859-x, все-таки могут использоваться, но вы все равно никогда не узнаете, что же это за кодировка. Фактически, я видел 8-битные ящики только у спамеров.
В конце концов, вы ведь храните ваши данные в UTF-8, так? Значит вы в любом случае не сможете перевести их обратно в ту локаль, которая была использована, если вы ее не знаете.
Доменные имена
У почтовых доменов те же самые ограничения как и в HTTP: они регистронезависимые, так что их следует нормализовывать в нижний регистр.
Поддомены
Некоторые адреса содержат ненужные поддомены: например, «email.msn.com» и «msn.com» являются одним и тем же почтовым доменом, кроме того, такие истории часто случаются в корпоративной среде (и это еще один хороший кандидат для каноникализации).
Интернационализированные домены (
IDN)IDN были созданы для того чтобы использовать местные символы Юникода в названиях доменов, кроме того, возможно создать домен и со специальными символами:
postmaster@→→→→→→→.ws
этот классно описывает круговорот воды в природе.
Как и HTTP, SMTP поддерживает лишь 7-битную кодировку, и для того чтобы справиться с этим несчастьем IDN конвертируются в Punycode, что позволяет имени домена конвертироваться в представление Юникод и обратно:
postmaster@xn--55gaaaaaa281gfaqg86dja792anqa.ws
Очень жаль, но существует возможность фишинга при использовании IDN. Юникод содержит несколько разных экземпляров некоторых символов ASCII. Это позволяет злоумышленнику создать сайт, название которого выглядит точно также как и оригинал из-за того, что некоторые символы в названии совпадают внешне, но не внутренне.
Это порождает несколько вопросов на которые следует ответить:
Должны ли мы дозволять IDN-адреса? Можем ли мы обеспечить саппорт пользователей службой поддержки (откуда у саппорта, например, клавиатуры с китайскими иероглифами?) Должны ли мы сохранять их в Юникоде или Punycode? Если мы сохраняем каноничные адреса, то в какой кодировке это делать? Поддерживает ли вообще наш почтовик (MTA) IDN, и в какой форме он ждет адреса при отправке писем?
IP Address syntax
Использование IP-адресов допустимо:
allen@[127.0.0.1] allen@[IPv6:0:0:1]
Однако такие адреса выглядят подозрительно, и вряд ли им стоит доверять.
Временные почтовые адреса
Существует множество сервисов, которые предоставляют пользователям временные почтовые адреса. Обычно это используется для анонимности или для того чтобы регистрироваться на недоверенных сайтах.
Даже такие сервисы как Hotmail и Yahoo предоставляют алиасы, которые могут быть использованы примерно тем же способом, то есть уничтожены через некоторое время. Не существует единой техники выявления таких адресов — в конце концов именно для этого они и предназначены. Они используют большущий набор доменных имен с постоянной ротацией для того чтобы быть на шаг впереди тех, кто пытается пресечь их деятельность.
Белый список используемых возможностей
Адреса электронной почты могут быть чудовищно сложными, но, навскидку, 99,99% (а может, и больше) придерживаются простых принципов, а остальные слишком утомительно поддерживать.
Итак, вам вероятно следует воздержаться от поддержки адреса, если он содержит:
- Зависимость от регистра
- Пробелы
- Кавычки или Эскейп-символы
- Специальные символы кроме
'.
_+-
- Айпишники в поле домена
- IDN
Конечно, это может создать проблемы некоторым пользователям, но и в этом случае они скорее всего попытаются использовать какой-нибудь другой адрес, который подойдет. Кроме того, это позволит вашему саппорту более качественно оказывать поддержку вне зависимости от пользовательской локали.
Еще я считаю, что вы должны поддерживать теги.
Если это необходимо, вы можете создать еще одно поле в базе с каноническим адресом, даже если считаете, что всю эту RFC-шную совместимость стоит поддерживать. Адрес в таком поле может быть:
- Приведен в нижний регистр
- Быть без тегов
- Транскодирован из Юникода в ASCII
- Без дублирующихся поддоменов
Несмотря на то, что этот совет может показаться слишком радикальным, это все равно лучше, чем слепо подчиняться стандартам. Как знать, может когда-нибудь такая упрощенная нотация станет новым стандартом?
RFC 5321 требует, чтобы мой SMTP-сервер с расширением службы Enhanced-Status-Codes отвечал «250 OK»
Прежде всего: сервер должен отвечать не 250 OK
, а 221 OK
на QUIT
команда.
Но я думаю, вы неправильно поняли, что здесь означает OK
, стандарт SMTP (без расширений) не заботится о том, что идет после кода состояния, это был тупой стандарт, и во время его реализации каждый почтовый сервер был открытым реле. Вы можете ответить с 221 Хорошего дня
и все еще соответствует RFC 5321.
Кроме того, RFC 5321 заменяет и включает в себя многие старые вещи (см. описания).
Важная часть для вас:
Этот документ является спецификацией основного протокола для Интернета. электронный почтовый транспорт. Он объединяет, обновляет и уточняет несколько предыдущих документов, делая все или часть большинства из них устаревший.
Он охватывает механизмы расширения SMTP и лучшие практики. для современного Интернета, , но не дает подробностей о определенные расширения .
В вашем примере, что касается RFC 5321, 221
— это код состояния, а все остальное — просто текст. Думаю, станет яснее, если вы прочитаете раздел терминации RFC5321:
https://www.rfc-editor.org/rfc/rfc5321#section-3.8
Итак, TL;DR: 221 2.0.0 Goodbye
идеально подходит для RFC 5321.
Имейте в виду, что «расширения» называются так не просто так, они построены поверх базового стандарта. Вместо того, чтобы заменить, они обеспечивают дополнение к нему.
Но не волнуйтесь, SMTP (и электронная почта в целом) — монстр Франкенштейна, единственная причина, по которой его не заменили полностью, — широкое распространение. Обеспечение такой обратной совместимости для стандарта, которому по сути более 30 лет, просто смешно в 21 веке.
А для еще большего спокойствия:
2.
2.3. Специальные вопросы с расширениями
Разрешены расширения, которые изменяют довольно основные свойства работы SMTP. Текст в других разделах этого документа следует понимать в этом контексте. В частности, расширения могут изменить минимальные ограничения, указанные в разделе 4.5.3, могут изменить требования к набору символов ASCII, как указано выше, или могут ввести некоторые дополнительные режимы обработки сообщений.
В частности, если расширение подразумевает, что путь доставки обычно поддерживает специальные функции этого расширения, а промежуточная SMTP-система находит следующий переход, который не поддерживает требуемое расширение, она МОЖЕТ выбрать, исходя из конкретного расширения и обстоятельств, повторно поставьте сообщение в очередь и повторите попытку позже и/или попробуйте другой хост MX. Если используется эта стратегия, время ожидания возврата к нерасширенному формату (если оно доступно) СЛЕДУЕТ быть меньше, чем обычное время ожидания возврата как недоставленного (например, если обычное время ожидания составляет три дня, время ожидания повторной очереди перед попыткой передачи почта без расширения может быть один день).
https://www.rfc-editor.org/rfc/rfc5321#section-2.2.3
Объяснение протокола SMTP (как работает электронная почта?) нажать кнопку «отправить»?
Как письмо попадает в почтовый ящик вашего друга?
В этой статье я собираюсь научить вас шаг за шагом всему пути сообщения электронной почты, начиная с момента, когда вы нажимаете кнопку «Отправить», и заканчивая тем, что оно попадает в почтовый ящик вашего друга.
Чтобы понять, как работает электронная почта, вам необходимо понимать интернет-протокол, называемый SMTP или «простой протокол передачи почты».
Начнем!
Что такое SMTP?
SMTP — это интернет-стандарт для отправки электронной почты в Интернете.
Если вы любите приключения и действительно хотите прочитать спецификации протокола, первоначальные спецификации для SMTP были опубликованы в RFC 821 в 1982 году. Позднее в RFC 5321 были введены дополнительные спецификации.0009
Должен предупредить вас, что эти RFC очень сухие и их довольно скучно читать.
Теперь вместо того, чтобы рассматривать RFC, я лучше объясню, как работает электронная почта и SMTP, на практическом примере.
Мотивирующий пример
В оставшейся части этой статьи я собираюсь объяснить протокол SMTP и принцип работы электронной почты, следуя пути сообщения электронной почты от одного человека Боб к другому Алисе .
Предположим, что у Боба есть учетная запись электронной почты в gmail, [email protected] , и у Алисы есть учетная запись электронной почты на yahoo, [email protected]
Боб хочет отправить электронное письмо Алисе. Он составляет свое сообщение в приложении, работающем на его MAC (приложение Apple Mail) , и он готов нажать «отправить».
Что я собираюсь сделать сейчас, так это отследить это сообщение на всем пути от ноутбука Боба до того, как оно достигнет ноутбука Алисы.
Сначала выложим всех участвующих в процессе игроков:
1- Пользовательский агент Боба Это приложение, работающее на ноутбуке Боба, которое он использует для составления, ответа и чтения своих сообщений электронной почты.
Боб использует приложение Apple Mail на своем MAC в качестве пользовательского агента.
Если Боб хочет прочитать свои сообщения электронной почты, его пользовательский агент получает их с почтового сервера Боба (я объясню, что это дальше). Если Боб хочет отправить сообщение электронной почты, он составляет сообщение в своем пользовательском агенте, а затем отправляет его на свой почтовый сервер для доставки нужному получателю.
2- Почтовый сервер БобаУ Боба есть учетная запись электронной почты на gmail.
Это означает, что в домене gmail.com есть удаленный компьютер, который управляет всеми сообщениями электронной почты, отправляемыми Бобу. Эта машина также отвечает за отправку сообщений электронной почты, отправленных Бобом, другим пользователям на других почтовых серверах.
Этот удаленный компьютер (или, точнее, приложение, работающее на этом удаленном компьютере) — это то, что мы называем почтовым сервером Боба.
Похож на почтовый сервер Боба, но это машина Yahoo, а не машина Gmail, потому что, как я упоминал ранее, у Алисы есть учетная запись электронной почты Yahoo.
4- Пользовательский агент Алисыснова похож на пользовательский агент Боба, это приложение, работающее на ноутбуке Алисы, которое позволяет ей получать электронные письма со своего почтового сервера для чтения. Это также позволяет ей составлять сообщения на своем ноутбуке и отправлять их на свой почтовый сервер, чтобы позже доставить их соответствующему получателю. У Алисы есть компьютер, и она использует Microsoft Outlook в качестве пользовательского агента.
Путешествие по электронной почте
Теперь вернемся к нашему сценарию, давайте проследим за сообщением по электронной почте, когда оно отправляется от Боба к Алисе на высоком уровне.
1- Боб открывает свое почтовое приложение, предоставляет адрес электронной почты Алисы (Alice@yahoo. com), пишет свое сообщение и нажимает кнопку «Отправить». отправить электронное письмо, составленное Бобом, на почтовый сервер Боба, где оно хранится для последующей доставки по адресу [email protected].
3- Почтовый сервер Боба видит, что есть сообщение, ожидающее доставки на адрес [email protected]. Он начинает связь с почтовым сервером yahoo.com, чтобы обеспечить доставку этого сообщения. Именно здесь в игру вступает протокол SMTP. SMTP — это протокол, который управляет связью между этими двумя почтовыми серверами. В нашем конкретном сценарии почтовый сервер Боба будет играть роль SMTP-клиента, а почтовый сервер Алисы будет играть роль SMTP-сервера.
4- После первоначального SMTP-квитирования между почтовыми серверами gmail и yahoo SMTP-клиент отправляет сообщение Боба на почтовый сервер Алисы.
5- Почтовый сервер Алисы получает сообщение и сохраняет его в ее почтовом ящике, чтобы она могла прочитать его позже.
6- В какой-то момент Алиса использует свой Microsoft Outlook для извлечения сообщений из своего почтового ящика и, в конце концов, читает сообщение Боба.
Я расскажу о том, как сообщения электронной почты доставляются от пользовательского агента Боба на его почтовый сервер (и от почтового сервера Алисы на ее пользовательский агент) позже.
Протокол SMTP
А пока давайте сосредоточимся на обмене данными между почтовым сервером Боба (работающим на машине gmail.com) и почтовым сервером Алисы (работающей на машине yahoo.com).
Помните, что почтовый сервер Боба должен был установить канал связи с почтовым сервером Алисы, чтобы доставить электронную почту Боба Алисе.
Также помните, что SMTP — это протокол, который управляет этой связью.
Вот схема последовательности всех событий, которые происходят, когда все работает правильно.
Протокол SMTP — это текстовый протокол, состоящий из команд и ответов.
SMTP-клиент (в нашем случае почтовый сервер Боба) отправляет SMTP-команды, тогда как SMTP-сервер (почтовый сервер Алисы) отвечает на эти команды числовыми кодами.
Некоторые примеры команд, которые используются в протоколе SMTP: EHLO , MAIL FROM , RCPT TO , DATA и QUIT.
Протокол SMTP состоит из трех основных фаз:
Первая: SMTP-квитирование
Сначала почтовый сервер Боба (SMTP-клиент) устанавливает SMTP-сервер отвечает кодом 220. (этот шаг не показан на диаграмме последовательности)
После того, как SMTP-клиент получит ответ 220 , начнется квитирование.
Общая цель этапа установления связи состоит в том, чтобы клиент и сервер идентифицировали себя, услуги, которые они могут предоставлять, а также личность отправителя и получателя электронной почты.
Он начинается с того, что почтовый сервер Боба отправляет команду EHLO на почтовый сервер Алисы и идентифицирует ее домен. Например, почтовый сервер Боба отправил бы «EHLO
Воспринимайте команду EHLO как приветственное сообщение, которое SMTP-клиент отправляет на SMTP-сервер. На самом деле в старом RFC она называлась командой HELO , но позже в новом RFC она была изменена, чтобы обеспечить более богатые возможности.
SMTP-сервер в Yahoo подтверждает сообщение EHLO , отвечая кодом « 250 » вместе со службами, которые может поддерживать SMTP-сервер. Клиенту и серверу важно договориться о службах и функциях, которые они могут поддерживать, до начала передачи сообщения.
Теперь, когда приветствие выполнено, пришло время клиенту отправить информацию об отправителе и получателе электронной почты.
Клиент SMTP возобновляет работу, отправляя команду «MAIL FROM» вместе с информацией об отправителе. В нашем сценарии это будет что-то вроде «ПОЧТА ОТ:
Когда SMTP-сервер получает эту команду, он снова отвечает тем же кодом 250 , чтобы указать, что у него нет проблем. прием сообщений от этого пользователя, Боб.
После этого клиент отправляет команду «RCPT TO» вместе с адресом электронной почты получателя «RCPT TO:
Помимо прочего, SMTP-сервер проверяет, существует ли пользователь «Алиса», и, если да, отправляет обратно подтверждение 250 , указывающее, что все в порядке с приемом сообщений от Боба для доставки Алисе.
На этом этап подтверждения связи завершен. Теперь давайте перейдем к мясным деталям. Как фактическое сообщение электронной почты передается с SMTP-клиента на SMTP-сервер?
Второй: передача сообщения
Прежде чем начать фактическую передачу сообщения, SMTP-клиент отправляет на сервер еще одну команду с именем «DATA» , чтобы убедиться, что сервер готов.
Почтовый сервер Алисы отвечает кодом «354» , указывающим, что он готов принять сообщение.
После получения этого кода с сервера клиент готов отправить сообщение электронной почты.
Хотите верьте, хотите нет, но фактическое сообщение электронной почты отправляется построчно. Однако серверная сторона не подтверждает получение каждой отдельной строки. Он просто ждет специальной строки «Конец почты», в которой есть только «.» (точка или точка) сама по себе.
Когда клиент отправляет «.» серверу, это означает, что клиент завершил отправку сообщения электронной почты. Это также сообщает серверу, что он может начать обработку сообщения сейчас.
После того, как почтовый сервер Алисы получает «.», он подтверждает получение всего сообщения, отправляя код 250 обратно клиенту.
Вот и все, вот как сообщение электронной почты, которое Боб составил на своем ноутбуке, попадает на машину Yahoo, ожидая, пока Алиса достанет и прочитает. Но все еще не хватает одной вещи, закрытия соединения между SMTP-клиентом и SMTP-сервером.
Третье: Закрытие соединения
Это очень просто и понятно.
Почтовый сервер Боба отправляет команду «ВЫЙТИ» на почтовый сервер Алисы, чтобы указать на свое намерение закрыть соединение, на что почтовый сервер Алисы отвечает кодом «221» .
Несколько слов о юзер-агентах
Давайте немного поговорим о юзер-агентах.
В нашем сценарии мы знаем, что Боб использовал свой пользовательский агент для отправки своего сообщения электронной почты на свой почтовый сервер. Мы также знаем, что Алиса использовала свой, чтобы получить и прочитать электронную почту Боба, но я никогда не говорил о механике этого.
Давайте сначала поговорим о стороне истории Боба, отправив его сообщение электронной почты на его почтовый сервер в gmail.
Оказывается, пользовательский агент Боба также может использовать протокол SMTP для отправки сообщения Боба на его почтовый сервер.
Подумай об этом.
Это точно такой же процесс, но с агентом пользователя Боба, являющимся SMTP-клиентом, и почтовым сервером Боба, являющимся SMTP-сервером.
Для Алисы это другое. Алиса не хочет отправлять электронное письмо на свой почтовый сервер. Она хочет получать и читать сообщения, уже хранящиеся в ее почтовом ящике Yahoo. Для этого есть два популярных протокола, которые может использовать ее пользовательский агент. Вы, наверное, слышали о них раньше: POP и IMAP.
Излишне говорить, что это не единственные способы взаимодействия с вашими почтовыми серверами из пользовательских агентов.
На самом деле в настоящее время наши пользовательские агенты часто являются нашими браузерами (мы заходим на yahoo.com или gmail.com из наших браузеров, чтобы отправлять/читать наши электронные письма). Наши браузеры отправляют и получают сообщений http , поэтому SMTP или POP/IMAP вообще не задействованы. Однако связь между почтовым сервером gmail и почтовым сервером yahoo по-прежнему регулируется протоколом SMTP, как я объяснял ранее.
Теперь мой вопрос к вам:
Ранее я упоминал, что SMTP-клиент отправляет «.» в отдельной строке, чтобы указать, что он передал все данные сообщения электронной почты.
У меня к вам вопрос: как вы думаете, что произойдет, если в сообщении электронной почты, составленном Бобом, будет знак «.